Imported Upstream version 4.0.0~alpha1

Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
This commit is contained in:
Jo Shields
2015-04-07 09:35:12 +01:00
parent 283343f570
commit 3c1f479b9d
22469 changed files with 2931443 additions and 869343 deletions

View File

@@ -0,0 +1,388 @@
//----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------------------
namespace System.ServiceModel.MsmqIntegration
{
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Runtime.Serialization;
using System.Diagnostics;
using System;
using System.IO;
using System.Globalization;
class ActiveXSerializer
{
byte[] byteBuffer;
char[] charBuffer;
object bufferLock = new object();
TKind[] TakeLockedBuffer<TKind>(out bool lockHeld, int size)
{
lockHeld = false;
Monitor.Enter(this.bufferLock, ref lockHeld);
if (typeof(byte) == typeof(TKind))
{
if (null == this.byteBuffer || size > this.byteBuffer.Length)
this.byteBuffer = new byte[size];
return this.byteBuffer as TKind[];
}
else if (typeof(char) == typeof(TKind))
{
if (null == this.charBuffer || size > this.charBuffer.Length)
this.charBuffer = new char[size];
return this.charBuffer as TKind[];
}
else
return null;
}
void ReleaseLockedBuffer()
{
Monitor.Exit(this.bufferLock);
}
public object Deserialize(MemoryStream stream, int bodyType)
{
if (stream == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("stream"));
VarEnum variantType = (VarEnum)bodyType;
byte[] bytes;
byte[] newBytes;
int size;
int count;
bool lockHeld;
switch (variantType)
{
case VarEnum.VT_LPSTR:
bytes = stream.ToArray();
size = bytes.Length;
lockHeld = false;
try
{
char[] buffer = TakeLockedBuffer<char>(out lockHeld, size);
System.Text.Encoding.ASCII.GetChars(bytes, 0, size, buffer, 0);
return new String(buffer, 0, size);
}
finally
{
if (lockHeld)
{
ReleaseLockedBuffer();
}
}
case VarEnum.VT_BSTR:
case VarEnum.VT_LPWSTR:
bytes = stream.ToArray();
size = bytes.Length / 2;
lockHeld = false;
try
{
char[] buffer = TakeLockedBuffer<char>(out lockHeld, size);
System.Text.Encoding.Unicode.GetChars(bytes, 0, size * 2, buffer, 0);
return new String(buffer, 0, size);
}
finally
{
if (lockHeld)
{
ReleaseLockedBuffer();
}
}
case VarEnum.VT_VECTOR | VarEnum.VT_UI1:
bytes = stream.ToArray();
newBytes = new byte[bytes.Length];
Array.Copy(bytes, newBytes, bytes.Length);
return newBytes;
case VarEnum.VT_BOOL:
bytes = new byte[1];
count = stream.Read(bytes, 0, 1);
if (count != 1)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
return (bytes[0] != 0);
case VarEnum.VT_CLSID:
bytes = new byte[16];
count = stream.Read(bytes, 0, 16);
if (count != 16)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
return new Guid(bytes);
case VarEnum.VT_CY:
bytes = new byte[8];
count = stream.Read(bytes, 0, 8);
if (count != 8)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
return Decimal.FromOACurrency(BitConverter.ToInt64(bytes, 0));
case VarEnum.VT_DATE:
bytes = new byte[8];
count = stream.Read(bytes, 0, 8);
if (count != 8)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
return new DateTime(BitConverter.ToInt64(bytes, 0));
case VarEnum.VT_I1:
case VarEnum.VT_UI1:
bytes = new byte[1];
count = stream.Read(bytes, 0, 1);
if (count != 1)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
return bytes[0];
case VarEnum.VT_I2:
bytes = new byte[2];
count = stream.Read(bytes, 0, 2);
if (count != 2)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
return BitConverter.ToInt16(bytes, 0);
case VarEnum.VT_UI2:
bytes = new byte[2];
count = stream.Read(bytes, 0, 2);
if (count != 2)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
return BitConverter.ToUInt16(bytes, 0);
case VarEnum.VT_I4:
bytes = new byte[4];
count = stream.Read(bytes, 0, 4);
if (count != 4)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
return BitConverter.ToInt32(bytes, 0);
case VarEnum.VT_UI4:
bytes = new byte[4];
count = stream.Read(bytes, 0, 4);
if (count != 4)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
return BitConverter.ToUInt32(bytes, 0);
case VarEnum.VT_I8:
bytes = new byte[8];
count = stream.Read(bytes, 0, 8);
if (count != 8)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
return BitConverter.ToInt64(bytes, 0);
case VarEnum.VT_UI8:
bytes = new byte[8];
count = stream.Read(bytes, 0, 8);
if (count != 8)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
return BitConverter.ToUInt64(bytes, 0);
case VarEnum.VT_R4:
bytes = new byte[4];
count = stream.Read(bytes, 0, 4);
if (count != 4)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
return BitConverter.ToSingle(bytes, 0);
case VarEnum.VT_R8:
bytes = new byte[8];
count = stream.Read(bytes, 0, 8);
if (count != 8)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqCannotDeserializeActiveXMessage)));
return BitConverter.ToDouble(bytes, 0);
case VarEnum.VT_NULL:
return null;
default:
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqInvalidTypeDeserialization)));
}
}
public void Serialize(Stream stream, object obj, ref int bodyType)
{
if (stream == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("stream"));
VarEnum variantType;
if (obj is string)
{
int size = ((string)obj).Length * 2;
bool lockHeld = false;
try
{
byte[] buffer = TakeLockedBuffer<byte>(out lockHeld, size);
System.Text.Encoding.Unicode.GetBytes(((string)obj).ToCharArray(), 0, size / 2, buffer, 0);
stream.Write(buffer, 0, size);
}
finally
{
if (lockHeld)
{
ReleaseLockedBuffer();
}
}
variantType = VarEnum.VT_LPWSTR;
}
else if (obj is byte[])
{
byte[] bytes = (byte[])obj;
stream.Write(bytes, 0, bytes.Length);
variantType = VarEnum.VT_UI1 | VarEnum.VT_VECTOR;
}
else if (obj is char[])
{
char[] chars = (char[])obj;
int size = chars.Length * 2;
bool lockHeld = false;
try
{
byte[] buffer = TakeLockedBuffer<byte>(out lockHeld, size);
System.Text.Encoding.Unicode.GetBytes(chars, 0, size / 2, buffer, 0);
stream.Write(buffer, 0, size);
}
finally
{
if (lockHeld)
{
ReleaseLockedBuffer();
}
}
variantType = VarEnum.VT_LPWSTR;
}
else if (obj is byte)
{
stream.Write(new byte[] { (byte)obj }, 0, 1);
variantType = VarEnum.VT_UI1;
}
else if (obj is bool)
{
if ((bool)obj)
stream.Write(new byte[] { 0xff }, 0, 1);
else
stream.Write(new byte[] { 0x00 }, 0, 1);
variantType = VarEnum.VT_BOOL;
}
else if (obj is char)
{
byte[] bytes = BitConverter.GetBytes((Char)obj);
stream.Write(bytes, 0, 2);
variantType = VarEnum.VT_UI2;
}
else if (obj is Decimal)
{
byte[] bytes = BitConverter.GetBytes(Decimal.ToOACurrency((Decimal)obj));
stream.Write(bytes, 0, 8);
variantType = VarEnum.VT_CY;
}
else if (obj is DateTime)
{
byte[] bytes = BitConverter.GetBytes(((DateTime)obj).Ticks);
stream.Write(bytes, 0, 8);
variantType = VarEnum.VT_DATE;
}
else if (obj is Double)
{
byte[] bytes = BitConverter.GetBytes((Double)obj);
stream.Write(bytes, 0, 8);
variantType = VarEnum.VT_R8;
}
else if (obj is Guid)
{
byte[] bytes = ((Guid)obj).ToByteArray();
stream.Write(bytes, 0, 16);
variantType = VarEnum.VT_CLSID;
}
else if (obj is Int16)
{
byte[] bytes = BitConverter.GetBytes((short)obj);
stream.Write(bytes, 0, 2);
variantType = VarEnum.VT_I2;
}
else if (obj is UInt16)
{
byte[] bytes = BitConverter.GetBytes((UInt16)obj);
stream.Write(bytes, 0, 2);
variantType = VarEnum.VT_UI2;
}
else if (obj is Int32)
{
byte[] bytes = BitConverter.GetBytes((int)obj);
stream.Write(bytes, 0, 4);
variantType = VarEnum.VT_I4;
}
else if (obj is UInt32)
{
byte[] bytes = BitConverter.GetBytes((UInt32)obj);
stream.Write(bytes, 0, 4);
variantType = VarEnum.VT_UI4;
}
else if (obj is Int64)
{
byte[] bytes = BitConverter.GetBytes((Int64)obj);
stream.Write(bytes, 0, 8);
variantType = VarEnum.VT_I8;
}
else if (obj is UInt64)
{
byte[] bytes = BitConverter.GetBytes((UInt64)obj);
stream.Write(bytes, 0, 8);
variantType = VarEnum.VT_UI8;
}
else if (obj is Single)
{
byte[] bytes = BitConverter.GetBytes((float)obj);
stream.Write(bytes, 0, 4);
variantType = VarEnum.VT_R4;
}
else
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.MsmqInvalidTypeSerialization)));
}
bodyType = (int)variantType;
}
}
}

View File

@@ -0,0 +1,124 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.MsmqIntegration
{
using System;
using System.ComponentModel;
using System.ServiceModel;
using System.Text;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.Globalization;
using System.Net;
using System.Net.Security;
using System.Runtime.Serialization;
using System.Security.Principal;
using System.ServiceModel.Channels;
using Config = System.ServiceModel.Configuration;
using System.ServiceModel.Security;
using System.Xml;
public class MsmqIntegrationBinding : MsmqBindingBase
{
// private BindingElements
MsmqIntegrationSecurity security = new MsmqIntegrationSecurity();
public MsmqIntegrationBinding()
{
Initialize();
}
public MsmqIntegrationBinding(string configurationName)
{
Initialize();
ApplyConfiguration(configurationName);
}
public MsmqIntegrationBinding(MsmqIntegrationSecurityMode securityMode)
{
if (!MsmqIntegrationSecurityModeHelper.IsDefined(securityMode))
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidEnumArgumentException("securityMode", (int)securityMode, typeof(MsmqIntegrationSecurityMode)));
Initialize();
this.security.Mode = securityMode;
}
public MsmqIntegrationSecurity Security
{
get { return this.security; }
set { this.security = value; }
}
internal Type[] TargetSerializationTypes
{
get
{
return (transport as MsmqIntegrationBindingElement).TargetSerializationTypes;
}
set
{
(transport as MsmqIntegrationBindingElement).TargetSerializationTypes = value;
}
}
[DefaultValue(MsmqIntegrationDefaults.SerializationFormat)]
public MsmqMessageSerializationFormat SerializationFormat
{
get { return (transport as MsmqIntegrationBindingElement).SerializationFormat; }
set { (transport as MsmqIntegrationBindingElement).SerializationFormat = value; }
}
[EditorBrowsable(EditorBrowsableState.Never)]
public bool ShouldSerializeSecurity()
{
if (this.security.Mode != MsmqIntegrationSecurityMode.Transport)
{
return true;
}
if (this.security.Transport.MsmqAuthenticationMode != MsmqDefaults.MsmqAuthenticationMode ||
this.security.Transport.MsmqEncryptionAlgorithm != MsmqDefaults.MsmqEncryptionAlgorithm ||
this.security.Transport.MsmqSecureHashAlgorithm != MsmqDefaults.MsmqSecureHashAlgorithm ||
this.security.Transport.MsmqProtectionLevel != MsmqDefaults.MsmqProtectionLevel)
{
return true;
}
return false;
}
void Initialize()
{
transport = new MsmqIntegrationBindingElement();
}
void ApplyConfiguration(string configurationName)
{
Config.MsmqIntegrationBindingCollectionElement section = Config.MsmqIntegrationBindingCollectionElement.GetBindingCollectionElement();
Config.MsmqIntegrationBindingElement element = section.Bindings[configurationName];
if (element == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(
SR.GetString(SR.ConfigInvalidBindingConfigurationName,
configurationName,
Config.ConfigurationStrings.MsmqIntegrationBindingCollectionElementName)));
}
else
{
element.ApplyConfiguration(this);
}
}
public override BindingElementCollection CreateBindingElements()
{ // return collection of BindingElements
BindingElementCollection bindingElements = new BindingElementCollection();
// order of BindingElements is important
// add transport
this.security.ConfigureTransportSecurity(transport);
bindingElements.Add(transport);
return bindingElements.Clone();
}
}
}

View File

@@ -0,0 +1,145 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.MsmqIntegration
{
using System.Net.Security;
using System.Runtime.Serialization;
using System.ServiceModel.Channels;
using System.Collections.Generic;
public sealed class MsmqIntegrationBindingElement : MsmqBindingElementBase
{
MsmqMessageSerializationFormat serializationFormat;
Type[] targetSerializationTypes;
public MsmqIntegrationBindingElement()
{
this.serializationFormat = MsmqIntegrationDefaults.SerializationFormat;
}
MsmqIntegrationBindingElement(MsmqIntegrationBindingElement other)
: base(other)
{
this.serializationFormat = other.serializationFormat;
if (other.targetSerializationTypes != null)
{
this.targetSerializationTypes = other.targetSerializationTypes.Clone() as Type[];
}
}
public override string Scheme { get { return "msmq.formatname"; } }
internal override MsmqUri.IAddressTranslator AddressTranslator
{
get
{
return MsmqUri.FormatNameAddressTranslator;
}
}
// applicable on: client, server
public MsmqMessageSerializationFormat SerializationFormat
{
get { return this.serializationFormat; }
set
{
if (!MsmqMessageSerializationFormatHelper.IsDefined(value))
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value"));
}
this.serializationFormat = value;
}
}
// applicable on: receiver
public Type[] TargetSerializationTypes
{
get
{
if (null == this.targetSerializationTypes)
return null;
else
return this.targetSerializationTypes.Clone() as Type[];
}
set
{
if (null == value)
this.targetSerializationTypes = null;
else
this.targetSerializationTypes = value.Clone() as Type[];
}
}
public override BindingElement Clone()
{
return new MsmqIntegrationBindingElement(this);
}
public override bool CanBuildChannelFactory<TChannel>(BindingContext context)
{
return typeof(TChannel) == typeof(IOutputChannel);
}
public override bool CanBuildChannelListener<TChannel>(BindingContext context)
{
return typeof(TChannel) == typeof(IInputChannel);
}
public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
{
if (context == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
}
if (typeof(TChannel) != typeof(IOutputChannel))
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("TChannel", SR.GetString(SR.ChannelTypeNotSupported, typeof(TChannel)));
}
MsmqChannelFactoryBase<IOutputChannel> factory = new MsmqIntegrationChannelFactory(this, context);
MsmqVerifier.VerifySender<IOutputChannel>(factory);
return (IChannelFactory<TChannel>)(object)factory;
}
public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
{
if (context == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
}
if (typeof(TChannel) != typeof(IInputChannel))
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("TChannel", SR.GetString(SR.ChannelTypeNotSupported, typeof(TChannel)));
}
MsmqIntegrationReceiveParameters receiveParameters = new MsmqIntegrationReceiveParameters(this);
MsmqIntegrationChannelListener listener = new MsmqIntegrationChannelListener(this, context, receiveParameters);
MsmqVerifier.VerifyReceiver(receiveParameters, listener.Uri);
return (IChannelListener<TChannel>)(object)listener;
}
public override T GetProperty<T>(BindingContext context)
{
if (context == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
}
if (typeof(T) == typeof(MessageVersion))
{
return (T)(object)(MessageVersion.None);
}
else
{
return base.GetProperty<T>(context);
}
}
}
}

View File

@@ -0,0 +1,178 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.MsmqIntegration
{
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Runtime.Serialization.Formatters.Binary; // for BinaryFormatter
using System.Xml.Serialization; // for XmlSerializer
using System.IO; // for Stream
using System.Collections.Specialized; //For HybridDictionary
using System.ServiceModel.Channels;
sealed class MsmqIntegrationChannelFactory : MsmqChannelFactoryBase<IOutputChannel>
{
ActiveXSerializer activeXSerializer;
BinaryFormatter binaryFormatter;
MsmqMessageSerializationFormat serializationFormat;
HybridDictionary xmlSerializerTable;
const int maxSerializerTableSize = 1024;
internal MsmqIntegrationChannelFactory(MsmqIntegrationBindingElement bindingElement, BindingContext context)
: base(bindingElement, context, null)
{
this.serializationFormat = bindingElement.SerializationFormat;
}
BinaryFormatter BinaryFormatter
{
get
{
if (this.binaryFormatter == null)
{
lock (ThisLock)
{
if (this.binaryFormatter == null)
this.binaryFormatter = new BinaryFormatter();
}
}
return this.binaryFormatter;
}
}
ActiveXSerializer ActiveXSerializer
{
get
{
if (this.activeXSerializer == null)
{
lock (ThisLock)
{
if (this.activeXSerializer == null)
this.activeXSerializer = new ActiveXSerializer();
}
}
return this.activeXSerializer;
}
}
XmlSerializer GetXmlSerializerForType(Type serializedType)
{
if (this.xmlSerializerTable == null)
{
lock (ThisLock)
{
if (this.xmlSerializerTable == null)
this.xmlSerializerTable = new HybridDictionary();
}
}
XmlSerializer serializer = (XmlSerializer)this.xmlSerializerTable[serializedType];
if (serializer != null)
{
return serializer;
}
lock (ThisLock)
{
if (this.xmlSerializerTable.Count >= maxSerializerTableSize)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new CommunicationException(SR.GetString(SR.MsmqSerializationTableFull, maxSerializerTableSize)));
// double-locking
serializer = (XmlSerializer)this.xmlSerializerTable[serializedType];
if (serializer != null)
{
return serializer;
}
serializer = new XmlSerializer(serializedType);
this.xmlSerializerTable[serializedType] = serializer;
return serializer;
}
}
public MsmqMessageSerializationFormat SerializationFormat
{
get
{
ThrowIfDisposed();
return this.serializationFormat;
}
}
protected override IOutputChannel OnCreateChannel(EndpointAddress to, Uri via)
{
base.ValidateScheme(via);
return new MsmqIntegrationOutputChannel(this, to, via, ManualAddressing);
}
//
// Returns stream containing serialized body
// In case of MsmqMessageSerializationFormat.Stream,
// returns body as Stream, and throws exception if body is not a Stream
//
internal Stream Serialize(MsmqIntegrationMessageProperty property)
{
Stream stream;
switch (this.SerializationFormat)
{
case MsmqMessageSerializationFormat.Xml:
stream = new MemoryStream();
XmlSerializer serializer = GetXmlSerializerForType(property.Body.GetType());
serializer.Serialize(stream, property.Body);
return stream;
case MsmqMessageSerializationFormat.Binary:
stream = new MemoryStream();
BinaryFormatter.Serialize(stream, property.Body);
// need to set BodyType to a magic number used by System.Messaging
property.BodyType = 0x300;
return stream;
case MsmqMessageSerializationFormat.ActiveX:
if (property.BodyType.HasValue)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MsmqCannotUseBodyTypeWithActiveXSerialization)));
}
stream = new MemoryStream();
int bodyType = 0;
ActiveXSerializer.Serialize(stream as MemoryStream, property.Body, ref bodyType);
property.BodyType = bodyType;
return stream;
case MsmqMessageSerializationFormat.ByteArray:
// body MUST be byte array
byte[] byteArray = property.Body as byte[];
if (byteArray == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqByteArrayBodyExpected)));
stream = new MemoryStream();
stream.Write(byteArray, 0, byteArray.Length);
return stream;
case MsmqMessageSerializationFormat.Stream:
// body MUST be a stream
Stream bodyStream = property.Body as Stream;
if (bodyStream == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqStreamBodyExpected)));
// NOTE: we don't copy here as a perf optimization, but this might be dangerous
return bodyStream;
default:
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.MsmqUnsupportedSerializationFormat, this.SerializationFormat)));
}
}
}
}

View File

@@ -0,0 +1,38 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.MsmqIntegration
{
using System.ServiceModel.Channels;
using System.Xml;
using System.Xml.Serialization;
sealed class MsmqIntegrationChannelListener
: MsmqInputChannelListenerBase
{
XmlSerializer[] xmlSerializerList;
internal MsmqIntegrationChannelListener(MsmqBindingElementBase bindingElement, BindingContext context, MsmqReceiveParameters receiveParameters)
: base(bindingElement, context, receiveParameters, null)
{
SetSecurityTokenAuthenticator(MsmqUri.FormatNameAddressTranslator.Scheme, context);
MsmqIntegrationReceiveParameters parameters = receiveParameters as MsmqIntegrationReceiveParameters;
xmlSerializerList = XmlSerializer.FromTypes(parameters.TargetSerializationTypes);
}
public override string Scheme
{
get { return "msmq.formatname"; }
}
internal XmlSerializer[] XmlSerializerList
{
get { return this.xmlSerializerList; }
}
protected override IInputChannel CreateInputChannel(MsmqInputChannelListenerBase listener)
{
return new MsmqIntegrationInputChannel(this);
}
}
}

View File

@@ -0,0 +1,23 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.MsmqIntegration
{
using System.ServiceModel.Channels;
sealed class MsmqIntegrationInputChannel
: MsmqInputChannelBase
{
public MsmqIntegrationInputChannel(MsmqIntegrationChannelListener listener)
: base(listener, new MsmqIntegrationMessagePool(MsmqDefaults.MaxPoolSize))
{ }
protected override Message DecodeMsmqMessage(MsmqInputMessage msmqMessage, MsmqMessageProperty property)
{
MsmqIntegrationChannelListener listener = this.Manager as MsmqIntegrationChannelListener;
return MsmqDecodeHelper.DecodeIntegrationDatagram(listener, this.MsmqReceiveHelper, msmqMessage as MsmqIntegrationInputMessage, property);
}
}
}

View File

@@ -0,0 +1,123 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.MsmqIntegration
{
using System.ServiceModel.Channels;
class MsmqIntegrationInputMessage : MsmqInputMessage
{
ByteProperty acknowledge;
StringProperty adminQueue;
IntProperty adminQueueLength;
IntProperty appSpecific;
IntProperty arrivedTime;
IntProperty senderIdType;
ByteProperty authenticated;
IntProperty bodyType;
BufferProperty correlationId;
StringProperty destinationQueue;
IntProperty destinationQueueLength;
BufferProperty extension;
IntProperty extensionLength;
StringProperty label;
IntProperty labelLength;
ByteProperty priority;
StringProperty responseFormatName;
IntProperty responseFormatNameLength;
IntProperty sentTime;
IntProperty timeToReachQueue;
IntProperty privacyLevel;
const int initialQueueNameLength = 256;
const int initialExtensionLength = 0;
const int initialLabelLength = 128;
const int maxSize = 4 * 1024 * 1024;
public MsmqIntegrationInputMessage()
: this(maxSize)
{ }
public MsmqIntegrationInputMessage(int maxBufferSize)
: this(new SizeQuota(maxBufferSize))
{ }
protected MsmqIntegrationInputMessage(SizeQuota bufferSizeQuota)
: base(22, bufferSizeQuota)
{
this.acknowledge = new ByteProperty(this, UnsafeNativeMethods.PROPID_M_ACKNOWLEDGE);
this.adminQueue = new StringProperty(this, UnsafeNativeMethods.PROPID_M_ADMIN_QUEUE, initialQueueNameLength);
this.adminQueueLength = new IntProperty(this, UnsafeNativeMethods.PROPID_M_ADMIN_QUEUE_LEN, initialQueueNameLength);
this.appSpecific = new IntProperty(this, UnsafeNativeMethods.PROPID_M_APPSPECIFIC);
this.arrivedTime = new IntProperty(this, UnsafeNativeMethods.PROPID_M_ARRIVEDTIME);
this.senderIdType = new IntProperty(this, UnsafeNativeMethods.PROPID_M_SENDERID_TYPE);
this.authenticated = new ByteProperty(this, UnsafeNativeMethods.PROPID_M_AUTHENTICATED);
this.bodyType = new IntProperty(this, UnsafeNativeMethods.PROPID_M_BODY_TYPE);
this.correlationId = new BufferProperty(this, UnsafeNativeMethods.PROPID_M_CORRELATIONID,
UnsafeNativeMethods.PROPID_M_CORRELATIONID_SIZE);
this.destinationQueue = new StringProperty(this, UnsafeNativeMethods.PROPID_M_DEST_FORMAT_NAME, initialQueueNameLength);
this.destinationQueueLength = new IntProperty(this, UnsafeNativeMethods.PROPID_M_DEST_FORMAT_NAME_LEN, initialQueueNameLength);
this.extension = new BufferProperty(this, UnsafeNativeMethods.PROPID_M_EXTENSION,
bufferSizeQuota.AllocIfAvailable(initialExtensionLength));
this.extensionLength = new IntProperty(this, UnsafeNativeMethods.PROPID_M_EXTENSION_LEN, initialExtensionLength);
this.label = new StringProperty(this, UnsafeNativeMethods.PROPID_M_LABEL, initialLabelLength);
this.labelLength = new IntProperty(this, UnsafeNativeMethods.PROPID_M_LABEL_LEN, initialLabelLength);
this.priority = new ByteProperty(this, UnsafeNativeMethods.PROPID_M_PRIORITY);
this.responseFormatName = new StringProperty(this, UnsafeNativeMethods.PROPID_M_RESP_FORMAT_NAME, initialQueueNameLength);
this.responseFormatNameLength = new IntProperty(this, UnsafeNativeMethods.PROPID_M_RESP_FORMAT_NAME_LEN, initialQueueNameLength);
this.sentTime = new IntProperty(this, UnsafeNativeMethods.PROPID_M_SENTTIME);
this.timeToReachQueue = new IntProperty(this, UnsafeNativeMethods.PROPID_M_TIME_TO_REACH_QUEUE);
this.privacyLevel = new IntProperty(this, UnsafeNativeMethods.PROPID_M_PRIV_LEVEL);
}
protected override void OnGrowBuffers(SizeQuota bufferSizeQuota)
{
base.OnGrowBuffers(bufferSizeQuota);
this.adminQueue.EnsureValueLength(this.adminQueueLength.Value);
this.responseFormatName.EnsureValueLength(this.responseFormatNameLength.Value);
this.destinationQueue.EnsureValueLength(this.destinationQueueLength.Value);
this.label.EnsureValueLength(this.labelLength.Value);
bufferSizeQuota.Alloc(this.extensionLength.Value);
this.extension.EnsureBufferLength(this.extensionLength.Value);
}
public void SetMessageProperties(MsmqIntegrationMessageProperty property)
{
property.AcknowledgeType = (System.Messaging.AcknowledgeTypes)this.acknowledge.Value;
property.Acknowledgment = (System.Messaging.Acknowledgment)this.Class.Value;
property.AdministrationQueue = GetQueueName(this.adminQueue.GetValue(this.adminQueueLength.Value));
property.AppSpecific = this.appSpecific.Value;
property.ArrivedTime = MsmqDateTime.ToDateTime(this.arrivedTime.Value).ToLocalTime();
property.Authenticated = this.authenticated.Value != 0;
property.BodyType = this.bodyType.Value;
property.CorrelationId = MsmqMessageId.ToString(this.correlationId.Buffer);
property.DestinationQueue = GetQueueName(this.destinationQueue.GetValue(this.destinationQueueLength.Value));
property.Extension = this.extension.GetBufferCopy(this.extensionLength.Value);
property.Id = MsmqMessageId.ToString(this.MessageId.Buffer);
property.Label = this.label.GetValue(this.labelLength.Value);
if (this.Class.Value == UnsafeNativeMethods.MQMSG_CLASS_NORMAL)
property.MessageType = System.Messaging.MessageType.Normal;
else if (this.Class.Value == UnsafeNativeMethods.MQMSG_CLASS_REPORT)
property.MessageType = System.Messaging.MessageType.Report;
else
property.MessageType = System.Messaging.MessageType.Acknowledgment;
property.Priority = (System.Messaging.MessagePriority)this.priority.Value;
property.ResponseQueue = GetQueueName(this.responseFormatName.GetValue(this.responseFormatNameLength.Value));
property.SenderId = this.SenderId.GetBufferCopy(this.SenderIdLength.Value);
property.SentTime = MsmqDateTime.ToDateTime(this.sentTime.Value).ToLocalTime();
property.InternalSetTimeToReachQueue(MsmqDuration.ToTimeSpan(this.timeToReachQueue.Value));
}
static Uri GetQueueName(string formatName)
{
if (String.IsNullOrEmpty(formatName))
return null;
else
return new Uri("msmq.formatname:" + formatName);
}
}
}

View File

@@ -0,0 +1,36 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.MsmqIntegration
{
using System.ServiceModel.Channels;
sealed class MsmqIntegrationMessagePool
: SynchronizedDisposablePool<MsmqIntegrationInputMessage>, IMsmqMessagePool
{
int maxPoolSize;
internal MsmqIntegrationMessagePool(int maxPoolSize)
: base(maxPoolSize)
{
this.maxPoolSize = maxPoolSize;
}
MsmqInputMessage IMsmqMessagePool.TakeMessage()
{
MsmqIntegrationInputMessage message = this.Take();
if (null == message)
message = new MsmqIntegrationInputMessage();
return message;
}
void IMsmqMessagePool.ReturnMessage(MsmqInputMessage message)
{
if (! this.Return(message as MsmqIntegrationInputMessage))
{
MsmqDiagnostics.PoolFull(this.maxPoolSize);
message.Dispose();
}
}
}
}

View File

@@ -0,0 +1,192 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.MsmqIntegration
{
using System.ComponentModel;
using System.Messaging;
using System.Runtime;
public sealed class MsmqIntegrationMessageProperty
{
public const string Name = "MsmqIntegrationMessageProperty";
public static MsmqIntegrationMessageProperty Get(System.ServiceModel.Channels.Message message)
{
if (null == message)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
if (null == message.Properties)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message.Properties");
return message.Properties[Name] as MsmqIntegrationMessageProperty;
}
object body;
public object Body
{
get { return this.body; }
set { this.body = value; }
}
AcknowledgeTypes? acknowledgeType = null;
public AcknowledgeTypes? AcknowledgeType
{
get { return this.acknowledgeType; }
set { this.acknowledgeType = value; }
}
Acknowledgment? acknowledgment = null;
public Acknowledgment? Acknowledgment
{
get { return this.acknowledgment; }
internal set { this.acknowledgment = value; }
}
Uri administrationQueue = null;
public Uri AdministrationQueue
{
get { return this.administrationQueue; }
set { this.administrationQueue = value; }
}
int? appSpecific = null;
public int? AppSpecific
{
get { return this.appSpecific; }
set { this.appSpecific = value; }
}
DateTime? arrivedTime = null;
public DateTime? ArrivedTime
{
get { return this.arrivedTime; }
internal set { this.arrivedTime = value; }
}
bool? authenticated = null;
public bool? Authenticated
{
get { return this.authenticated; }
internal set { this.authenticated = value; }
}
int? bodyType = null;
public int? BodyType
{
get { return this.bodyType; }
set { this.bodyType = value; }
}
string correlationId = null;
public string CorrelationId
{
get { return this.correlationId; }
set { this.correlationId = value; }
}
Uri destinationQueue = null;
public Uri DestinationQueue
{
get { return this.destinationQueue; }
internal set { this.destinationQueue = value; }
}
byte[] extension = null;
public byte[] Extension
{
get { return this.extension; }
set { this.extension = value; }
}
string id = null;
public string Id
{
get { return this.id; }
internal set { this.id = value; }
}
string label = null;
public string Label
{
get { return this.label; }
set { this.label = value; }
}
MessageType? messageType = null;
public MessageType? MessageType
{
get { return this.messageType; }
internal set { this.messageType = value; }
}
MessagePriority? priority = null;
public MessagePriority? Priority
{
get { return this.priority; }
set
{
ValidateMessagePriority(value);
this.priority = value;
}
}
Uri responseQueue = null;
public Uri ResponseQueue
{
get { return this.responseQueue; }
set { this.responseQueue = value; }
}
byte[] senderId = null;
public byte[] SenderId
{
get { return this.senderId; }
internal set { this.senderId = value; }
}
DateTime? sentTime = null;
public DateTime? SentTime
{
get { return this.sentTime; }
internal set { this.sentTime = value; }
}
TimeSpan? timeToReachQueue = null;
public TimeSpan? TimeToReachQueue
{
get { return this.timeToReachQueue; }
set
{
ValidateTimeToReachQueue(value);
this.timeToReachQueue = value;
}
}
internal void InternalSetTimeToReachQueue(TimeSpan timeout)
{
this.timeToReachQueue = timeout;
}
static void ValidateMessagePriority(MessagePriority? priority)
{
if (priority.HasValue && (priority.Value < MessagePriority.Lowest || priority.Value > MessagePriority.Highest))
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidEnumArgumentException("priority", (int)priority, typeof(MessagePriority)));
}
static void ValidateTimeToReachQueue(TimeSpan? timeout)
{
if (timeout.HasValue && timeout.Value < TimeSpan.Zero)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", timeout,
SR.GetString(SR.SFxTimeoutOutOfRange0)));
}
if (timeout.HasValue && TimeoutHelper.IsTooLarge(timeout.Value))
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", timeout,
SR.GetString(SR.SFxTimeoutOutOfRangeTooBig)));
}
}
}
}

View File

@@ -0,0 +1,292 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.MsmqIntegration
{
using System.IO;
using System.Runtime;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Diagnostics;
using System.ServiceModel.Security.Tokens;
sealed class MsmqIntegrationOutputChannel : TransportOutputChannel
{
MsmqQueue msmqQueue;
MsmqTransactionMode transactionMode;
MsmqIntegrationChannelFactory factory;
SecurityTokenProviderContainer certificateTokenProvider;
public MsmqIntegrationOutputChannel(MsmqIntegrationChannelFactory factory, EndpointAddress to, Uri via, bool manualAddressing)
: base(factory, to, via, manualAddressing, factory.MessageVersion)
{
this.factory = factory;
if (factory.IsMsmqX509SecurityConfigured)
{
this.certificateTokenProvider = factory.CreateX509TokenProvider(to, via);
}
}
void CloseQueue()
{
if (null != this.msmqQueue)
this.msmqQueue.Dispose();
this.msmqQueue = null;
}
void OnCloseCore(bool isAborting, TimeSpan timeout)
{
this.CloseQueue();
if (this.certificateTokenProvider != null)
{
if (isAborting)
this.certificateTokenProvider.Abort();
else
this.certificateTokenProvider.Close(timeout);
}
}
protected override void OnAbort()
{
this.OnCloseCore(true, TimeSpan.Zero);
}
protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
{
this.OnCloseCore(false, timeout);
return new CompletedAsyncResult(callback, state);
}
protected override void OnEndClose(IAsyncResult result)
{
CompletedAsyncResult.End(result);
}
protected override void OnClose(TimeSpan timeout)
{
this.OnCloseCore(false, timeout);
}
void OpenQueue()
{
try
{
this.msmqQueue = new MsmqQueue(this.factory.AddressTranslator.UriToFormatName(this.RemoteAddress.Uri), UnsafeNativeMethods.MQ_SEND_ACCESS);
}
catch (MsmqException ex)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ex.Normalized);
}
if (this.factory.ExactlyOnce)
{
this.transactionMode = MsmqTransactionMode.CurrentOrSingle;
}
else
{
this.transactionMode = MsmqTransactionMode.None;
}
}
void OnOpenCore(TimeSpan timeout)
{
OpenQueue();
if (this.certificateTokenProvider != null)
{
this.certificateTokenProvider.Open(timeout);
}
}
protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
{
OnOpenCore(timeout);
return new CompletedAsyncResult(callback, state);
}
protected override void OnEndOpen(IAsyncResult result)
{
CompletedAsyncResult.End(result);
}
protected override void OnOpen(TimeSpan timeout)
{
OnOpenCore(timeout);
}
protected override IAsyncResult OnBeginSend(Message message, TimeSpan timeout, AsyncCallback callback, object state)
{
OnSend(message, timeout);
return new CompletedAsyncResult(callback, state);
}
protected override void OnEndSend(IAsyncResult result)
{
CompletedAsyncResult.End(result);
}
protected override void OnSend(Message message, TimeSpan timeout)
{
MessageProperties properties = message.Properties;
Stream stream = null;
MsmqIntegrationMessageProperty property = MsmqIntegrationMessageProperty.Get(message);
if (null == property)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(SR.GetString(SR.MsmqMessageDoesntHaveIntegrationProperty)));
if (null != property.Body)
stream = this.factory.Serialize(property);
int size;
if (stream == null)
{
size = 0;
}
else
{
if (stream.Length > int.MaxValue)
{
throw TraceUtility.ThrowHelperError(new ProtocolException(SR.GetString(SR.MessageSizeMustBeInIntegerRange)), message);
}
size = (int)stream.Length;
}
using (MsmqIntegrationOutputMessage msmqMessage = new MsmqIntegrationOutputMessage(this.factory, size, this.RemoteAddress, property))
{
msmqMessage.ApplyCertificateIfNeeded(this.certificateTokenProvider, this.factory.MsmqTransportSecurity.MsmqAuthenticationMode, timeout);
if (stream != null)
{
stream.Position = 0;
for (int bytesRemaining = size; bytesRemaining > 0; )
{
int bytesRead = stream.Read(msmqMessage.Body.Buffer, 0, bytesRemaining);
bytesRemaining -= bytesRead;
}
}
bool lockHeld = false;
try
{
Msmq.EnterXPSendLock(out lockHeld, this.factory.MsmqTransportSecurity.MsmqProtectionLevel);
this.msmqQueue.Send(msmqMessage, this.transactionMode);
MsmqDiagnostics.DatagramSent(msmqMessage.MessageId, message);
property.Id = MsmqMessageId.ToString(msmqMessage.MessageId.Buffer);
}
catch (MsmqException ex)
{
if (ex.FaultSender)
this.Fault();
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ex.Normalized);
}
finally
{
if (lockHeld)
{
Msmq.LeaveXPSendLock();
}
}
}
}
class MsmqIntegrationOutputMessage : MsmqOutputMessage<IOutputChannel>
{
ByteProperty acknowledge;
StringProperty adminQueue;
IntProperty appSpecific;
BufferProperty correlationId;
BufferProperty extension;
StringProperty label;
ByteProperty priority;
StringProperty responseQueue;
public MsmqIntegrationOutputMessage(
MsmqChannelFactoryBase<IOutputChannel> factory,
int bodySize,
EndpointAddress remoteAddress,
MsmqIntegrationMessageProperty property)
: base(factory, bodySize, remoteAddress, 8)
{
if (null == property)
{
Fx.Assert("MsmqIntegrationMessageProperty expected");
}
if (property.AcknowledgeType.HasValue)
EnsureAcknowledgeProperty((byte)property.AcknowledgeType.Value);
if (null != property.AdministrationQueue)
EnsureAdminQueueProperty(property.AdministrationQueue, false);
if (property.AppSpecific.HasValue)
this.appSpecific = new IntProperty(this, UnsafeNativeMethods.PROPID_M_APPSPECIFIC, property.AppSpecific.Value);
if (property.BodyType.HasValue)
EnsureBodyTypeProperty(property.BodyType.Value);
if (null != property.CorrelationId)
this.correlationId = new BufferProperty(this, UnsafeNativeMethods.PROPID_M_CORRELATIONID, MsmqMessageId.FromString(property.CorrelationId));
if (null != property.Extension)
this.extension = new BufferProperty(this, UnsafeNativeMethods.PROPID_M_EXTENSION, property.Extension);
if (null != property.Label)
this.label = new StringProperty(this, UnsafeNativeMethods.PROPID_M_LABEL, property.Label);
if (property.Priority.HasValue)
this.priority = new ByteProperty(this, UnsafeNativeMethods.PROPID_M_PRIORITY, (byte)property.Priority.Value);
if (null != property.ResponseQueue)
EnsureResponseQueueProperty(property.ResponseQueue);
if (property.TimeToReachQueue.HasValue)
EnsureTimeToReachQueueProperty(MsmqDuration.FromTimeSpan(property.TimeToReachQueue.Value));
}
void EnsureAcknowledgeProperty(byte value)
{
if (this.acknowledge == null)
{
this.acknowledge = new ByteProperty(this, UnsafeNativeMethods.PROPID_M_ACKNOWLEDGE);
}
this.acknowledge.Value = value;
}
void EnsureAdminQueueProperty(Uri value, bool useNetMsmqTranslator)
{
if (null != value)
{
string queueName = useNetMsmqTranslator ?
MsmqUri.NetMsmqAddressTranslator.UriToFormatName(value) :
MsmqUri.FormatNameAddressTranslator.UriToFormatName(value);
if (this.adminQueue == null)
{
this.adminQueue = new StringProperty(this, UnsafeNativeMethods.PROPID_M_ADMIN_QUEUE, queueName);
}
else
{
this.adminQueue.SetValue(queueName);
}
}
}
void EnsureResponseQueueProperty(Uri value)
{
if (null != value)
{
string queueName = MsmqUri.FormatNameAddressTranslator.UriToFormatName(value);
if (this.responseQueue == null)
{
this.responseQueue = new StringProperty(this, UnsafeNativeMethods.PROPID_M_RESP_FORMAT_NAME, queueName);
}
else
{
this.responseQueue.SetValue(queueName);
}
}
}
}
}
}

View File

@@ -0,0 +1,40 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.MsmqIntegration
{
using System.Collections.Generic;
using System.ServiceModel.Channels;
sealed class MsmqIntegrationReceiveParameters
: MsmqReceiveParameters
{
MsmqMessageSerializationFormat serializationFormat;
Type[] targetSerializationTypes;
internal MsmqIntegrationReceiveParameters(MsmqIntegrationBindingElement bindingElement)
: base(bindingElement)
{
this.serializationFormat = bindingElement.SerializationFormat;
List<Type> knownTypes = new List<Type>();
if (null != bindingElement.TargetSerializationTypes)
{
foreach (Type type in bindingElement.TargetSerializationTypes)
if (! knownTypes.Contains(type))
knownTypes.Add(type);
}
this.targetSerializationTypes = knownTypes.ToArray();
}
internal MsmqMessageSerializationFormat SerializationFormat
{
get { return this.serializationFormat; }
}
internal Type[] TargetSerializationTypes
{
get { return this.targetSerializationTypes; }
}
}
}

View File

@@ -0,0 +1,53 @@
//----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------------------
namespace System.ServiceModel.MsmqIntegration
{
using System.ComponentModel;
using System.Net.Security;
using System.ServiceModel.Channels;
public sealed class MsmqIntegrationSecurity
{
internal const MsmqIntegrationSecurityMode DefaultMode = MsmqIntegrationSecurityMode.Transport;
MsmqIntegrationSecurityMode mode;
MsmqTransportSecurity transportSecurity;
public MsmqIntegrationSecurity()
{
this.mode = DefaultMode;
this.transportSecurity = new MsmqTransportSecurity();
}
[DefaultValue(MsmqIntegrationSecurity.DefaultMode)]
public MsmqIntegrationSecurityMode Mode
{
get { return this.mode; }
set
{
if (!MsmqIntegrationSecurityModeHelper.IsDefined(value))
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value"));
}
this.mode = value;
}
}
public MsmqTransportSecurity Transport
{
get { return this.transportSecurity; }
set { this.transportSecurity = value; }
}
internal void ConfigureTransportSecurity(MsmqBindingElementBase msmq)
{
if (this.mode == MsmqIntegrationSecurityMode.Transport)
msmq.MsmqTransportSecurity = this.Transport;
else
msmq.MsmqTransportSecurity.Disable();
}
}
}

View File

@@ -0,0 +1,22 @@
//----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------------------
namespace System.ServiceModel.MsmqIntegration
{
public enum MsmqIntegrationSecurityMode
{
None,
Transport
}
static class MsmqIntegrationSecurityModeHelper
{
internal static bool IsDefined(MsmqIntegrationSecurityMode value)
{
return (value == MsmqIntegrationSecurityMode.Transport
|| value == MsmqIntegrationSecurityMode.None);
}
}
}

View File

@@ -0,0 +1,116 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.MsmqIntegration
{
using System.ServiceModel;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
using System.Collections.ObjectModel;
using System.Collections.Generic;
class MsmqIntegrationValidationBehavior : IEndpointBehavior, IServiceBehavior
{
static MsmqIntegrationValidationBehavior instance;
internal static MsmqIntegrationValidationBehavior Instance
{
get
{
if (instance == null)
instance = new MsmqIntegrationValidationBehavior();
return instance;
}
}
MsmqIntegrationValidationBehavior() { }
void IEndpointBehavior.Validate(ServiceEndpoint serviceEndpoint)
{
if (serviceEndpoint == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("serviceEndpoint");
ContractDescription contract = serviceEndpoint.Contract;
Binding binding = serviceEndpoint.Binding;
if (NeedValidateBinding(binding))
{
ValidateHelper(contract, binding, null);
}
}
void IEndpointBehavior.AddBindingParameters(ServiceEndpoint serviceEndpoint, BindingParameterCollection bindingParameters)
{
}
void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, EndpointDispatcher endpointDispatcher)
{
}
void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime behavior)
{
}
void IServiceBehavior.AddBindingParameters(ServiceDescription description, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection parameters)
{
}
void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
{
}
void IServiceBehavior.Validate(ServiceDescription description, ServiceHostBase serviceHostBase)
{
if (description == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("description");
for (int i = 0; i < description.Endpoints.Count; i++)
{
ServiceEndpoint endpoint = description.Endpoints[i];
if (NeedValidateBinding(endpoint.Binding))
{
ValidateHelper(endpoint.Contract, endpoint.Binding, description);
break;
}
}
}
bool NeedValidateBinding(Binding binding)
{
if (binding is MsmqIntegrationBinding)
return true;
if (binding is CustomBinding)
{
CustomBinding customBinding = new CustomBinding(binding);
return (customBinding.Elements.Find<MsmqIntegrationBindingElement>() != null);
}
return false;
}
void ValidateHelper(ContractDescription contract, Binding binding, ServiceDescription description)
{
foreach (OperationDescription operation in contract.Operations)
{
// since this is one-way, we can only have one message (one-way requirement is validated elsewhere)
MessageDescription message = operation.Messages[0];
if ((message.Body.Parts.Count == 0) && (message.Headers.Count == 0))
// all message parts are properties, great
continue;
if (message.Body.Parts.Count == 1) // Single MsmqMessage<> argument is also legal
{
Type type = message.Body.Parts[0].Type;
if (type.IsGenericType && (type.GetGenericTypeDefinition() == typeof(MsmqMessage<>)))
continue;
}
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
SR.GetString(SR.MsmqInvalidServiceOperationForMsmqIntegrationBinding, binding.Name, operation.Name, contract.Name)));
}
}
}
}

View File

@@ -0,0 +1,138 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.MsmqIntegration
{
using System.Messaging;
using System.ServiceModel;
using System.ServiceModel.Channels;
[MessageContract(IsWrapped = false)]
public sealed class MsmqMessage<T>
{
[MessageProperty(Name = MsmqIntegrationMessageProperty.Name)]
MsmqIntegrationMessageProperty property;
public MsmqMessage(T body)
{
if (body == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("body");
this.property = new MsmqIntegrationMessageProperty();
this.property.Body = body;
}
internal MsmqMessage()
{ }
public T Body
{
get { return (T)this.property.Body; }
set
{
if (value == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
this.property.Body = value;
}
}
public AcknowledgeTypes? AcknowledgeType
{
get { return this.property.AcknowledgeType; }
set { this.property.AcknowledgeType = value; }
}
public Acknowledgment? Acknowledgment
{
get { return this.property.Acknowledgment; }
}
public Uri AdministrationQueue
{
get { return this.property.AdministrationQueue; }
set { this.property.AdministrationQueue = value; }
}
public int? AppSpecific
{
get { return this.property.AppSpecific; }
set { this.property.AppSpecific = value; }
}
public DateTime? ArrivedTime
{
get { return this.property.ArrivedTime; }
}
public bool? Authenticated
{
get { return this.property.Authenticated; }
}
public int? BodyType
{
get { return this.property.BodyType; }
set { this.property.BodyType = value; }
}
public string CorrelationId
{
get { return this.property.CorrelationId; }
set { this.property.CorrelationId = value; }
}
public Uri DestinationQueue
{
get { return this.property.DestinationQueue; }
}
public byte[] Extension
{
get { return this.property.Extension; }
set { this.property.Extension = value; }
}
public string Id
{
get { return this.property.Id; }
}
public string Label
{
get { return this.property.Label; }
set { this.property.Label = value; }
}
public MessageType? MessageType
{
get { return this.property.MessageType; }
}
public MessagePriority? Priority
{
get { return this.property.Priority; }
set { this.property.Priority = value; }
}
public Uri ResponseQueue
{
get { return this.property.ResponseQueue; }
set { this.property.ResponseQueue = value; }
}
public byte[] SenderId
{
get { return this.property.SenderId; }
}
public DateTime? SentTime
{
get { return this.property.SentTime; }
}
public TimeSpan? TimeToReachQueue
{
get { return this.property.TimeToReachQueue; }
set { this.property.TimeToReachQueue = value; }
}
}
}

View File

@@ -0,0 +1,28 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.MsmqIntegration
{
public enum MsmqMessageSerializationFormat
{
Xml,
Binary,
ActiveX,
ByteArray,
Stream
}
static class MsmqMessageSerializationFormatHelper
{
internal static bool IsDefined(MsmqMessageSerializationFormat value)
{
return
value == MsmqMessageSerializationFormat.ActiveX ||
value == MsmqMessageSerializationFormat.Binary ||
value == MsmqMessageSerializationFormat.ByteArray ||
value == MsmqMessageSerializationFormat.Stream ||
value == MsmqMessageSerializationFormat.Xml;
}
}
}