1 //------------------------------------------------------------ 2 // Copyright (c) Microsoft Corporation. All rights reserved. 3 //------------------------------------------------------------ 4 5 namespace System.ServiceModel 6 { 7 using System.Text; 8 using System.Globalization; 9 using System.Runtime.Serialization; 10 using System.Runtime.InteropServices; 11 using System.Runtime.Versioning; 12 using System.ServiceModel.Channels; 13 14 [Serializable] 15 public class MsmqException : ExternalException 16 { 17 [NonSerialized] 18 bool? faultSender = null; 19 [NonSerialized] 20 bool? faultReceiver = null; 21 [NonSerialized] 22 Type outerExceptionType = null; 23 MsmqException()24 public MsmqException() 25 { 26 } 27 MsmqException(string message)28 public MsmqException(string message) 29 : base(message) 30 { 31 } 32 MsmqException(string message, int error)33 public MsmqException(string message, int error) 34 : base(message, error) 35 { 36 } 37 MsmqException(string message, Exception inner)38 public MsmqException(string message, Exception inner) 39 : base(message, inner) 40 { 41 } 42 MsmqException(SerializationInfo info, StreamingContext context)43 protected MsmqException(SerializationInfo info, StreamingContext context) 44 : base(info, context) 45 { 46 } 47 48 internal bool FaultSender 49 { 50 get 51 { 52 TuneBehavior(); 53 return this.faultSender.Value; 54 } 55 } 56 57 internal bool FaultReceiver 58 { 59 get 60 { 61 TuneBehavior(); 62 return this.faultReceiver.Value; 63 } 64 } 65 TuneBehavior()66 void TuneBehavior() 67 { 68 if (this.faultSender.HasValue && this.faultReceiver.HasValue) 69 return; 70 71 switch (this.ErrorCode) 72 { 73 // configuration erors 74 case UnsafeNativeMethods.MQ_ERROR_ACCESS_DENIED: 75 faultSender = true; faultReceiver = true; outerExceptionType = typeof(AddressAccessDeniedException); break; 76 case UnsafeNativeMethods.MQ_ERROR_NO_INTERNAL_USER_CERT: 77 faultSender = true; faultReceiver = true; outerExceptionType = typeof(CommunicationException); break; 78 case UnsafeNativeMethods.MQ_ERROR_QUEUE_DELETED: 79 faultSender = true; faultReceiver = true; outerExceptionType = typeof(EndpointNotFoundException); break; 80 case UnsafeNativeMethods.MQ_ERROR_QUEUE_NOT_FOUND: 81 faultSender = true; faultReceiver = true; outerExceptionType = typeof(EndpointNotFoundException); break; 82 case UnsafeNativeMethods.MQ_ERROR_CERTIFICATE_NOT_PROVIDED: 83 faultSender = true; faultReceiver = true; outerExceptionType = typeof(CommunicationException); break; 84 case UnsafeNativeMethods.MQ_ERROR_INVALID_CERTIFICATE: 85 faultSender = true; faultReceiver = true; outerExceptionType = typeof(CommunicationException); break; 86 case UnsafeNativeMethods.MQ_ERROR_CANNOT_CREATE_CERT_STORE: 87 faultSender = true; faultReceiver = true; outerExceptionType = typeof(CommunicationException); break; 88 case UnsafeNativeMethods.MQ_ERROR_CORRUPTED_PERSONAL_CERT_STORE: 89 faultSender = true; faultReceiver = true; outerExceptionType = typeof(CommunicationException); break; 90 case UnsafeNativeMethods.MQ_ERROR_COULD_NOT_GET_USER_SID: 91 faultSender = true; faultReceiver = true; outerExceptionType = typeof(CommunicationException); break; 92 case UnsafeNativeMethods.MQ_ERROR_ILLEGAL_FORMATNAME: 93 faultSender = false; faultReceiver = false; outerExceptionType = typeof(ArgumentException); break; 94 case UnsafeNativeMethods.MQ_ERROR_ILLEGAL_QUEUE_PATHNAME: 95 faultSender = false; faultReceiver = false; outerExceptionType = typeof(ArgumentException); break; 96 case UnsafeNativeMethods.MQ_ERROR_UNSUPPORTED_FORMATNAME_OPERATION: 97 faultSender = true; faultReceiver = true; outerExceptionType = typeof(ArgumentException); break; 98 case UnsafeNativeMethods.MQ_ERROR_CANNOT_HASH_DATA_EX: 99 faultSender = true; faultReceiver = true; outerExceptionType = typeof(CommunicationException); break; 100 case UnsafeNativeMethods.MQ_ERROR_CANNOT_SIGN_DATA_EX: 101 faultSender = true; faultReceiver = true; outerExceptionType = typeof(CommunicationException); break; 102 case UnsafeNativeMethods.MQ_ERROR_FAIL_VERIFY_SIGNATURE_EX: 103 faultSender = true; faultReceiver = true; outerExceptionType = typeof(CommunicationException); break; 104 case UnsafeNativeMethods.MQ_ERROR_BAD_SECURITY_CONTEXT: 105 faultSender = true; faultReceiver = true; outerExceptionType = typeof(CommunicationException); break; 106 case UnsafeNativeMethods.MQ_ERROR_PRIVILEGE_NOT_HELD: 107 faultSender = true; faultReceiver = true; outerExceptionType = typeof(CommunicationException); break; 108 case UnsafeNativeMethods.MQ_ERROR_SHARING_VIOLATION: 109 faultSender = true; faultReceiver = true; outerExceptionType = typeof(AddressAccessDeniedException); break; 110 // transient errors 111 case UnsafeNativeMethods.MQ_ERROR_DTC_CONNECT: 112 faultSender = false; faultReceiver = true; outerExceptionType = typeof(CommunicationException); break; 113 case UnsafeNativeMethods.MQ_ERROR_IO_TIMEOUT: 114 faultSender = false; faultReceiver = false; outerExceptionType = typeof(TimeoutException); break; 115 case UnsafeNativeMethods.MQ_ERROR_QUEUE_NOT_AVAILABLE: 116 faultSender = false; faultReceiver = true; outerExceptionType = typeof(EndpointNotFoundException); break; 117 case UnsafeNativeMethods.MQ_ERROR_REMOTE_MACHINE_NOT_AVAILABLE: 118 faultSender = false; faultReceiver = true; outerExceptionType = typeof(EndpointNotFoundException); break; 119 case UnsafeNativeMethods.MQ_ERROR_SERVICE_NOT_AVAILABLE: 120 faultSender = false; faultReceiver = true; outerExceptionType = typeof(EndpointNotFoundException); break; 121 case UnsafeNativeMethods.MQ_ERROR_INSUFFICIENT_RESOURCES: 122 faultSender = true; faultReceiver = true; outerExceptionType = typeof(CommunicationException); break; 123 case UnsafeNativeMethods.MQ_ERROR_MESSAGE_STORAGE_FAILED: 124 faultSender = true; faultReceiver = true; outerExceptionType = typeof(CommunicationException); break; 125 case UnsafeNativeMethods.MQ_ERROR_TRANSACTION_ENLIST: 126 faultSender = false; faultReceiver = true; outerExceptionType = typeof(CommunicationException); break; 127 case UnsafeNativeMethods.MQ_ERROR_TRANSACTION_IMPORT: 128 faultSender = true; faultReceiver = true; outerExceptionType = typeof(CommunicationException); break; 129 case UnsafeNativeMethods.MQ_ERROR_TRANSACTION_USAGE: 130 faultSender = true; faultReceiver = true; outerExceptionType = typeof(InvalidOperationException); break; 131 case UnsafeNativeMethods.MQ_ERROR_STALE_HANDLE: 132 faultSender = false; faultReceiver = false; outerExceptionType = typeof(InvalidOperationException); break; 133 // malformed messages 134 case UnsafeNativeMethods.MQ_ERROR_ILLEGAL_MQQMPROPS: 135 faultSender = true; faultReceiver = true; outerExceptionType = typeof(CommunicationException); break; 136 case UnsafeNativeMethods.MQ_ERROR_INSUFFICIENT_PROPERTIES: 137 faultSender = true; faultReceiver = true; outerExceptionType = typeof(CommunicationException); break; 138 default: 139 faultSender = true; faultReceiver = true; outerExceptionType = null; break; 140 } 141 } 142 143 internal Exception Normalized 144 { 145 get 146 { 147 TuneBehavior(); 148 if (null != this.outerExceptionType) 149 return Activator.CreateInstance(this.outerExceptionType, new object[] { this.Message, this }) as Exception; 150 else 151 return this; 152 } 153 } 154 } 155 156 static class MsmqError 157 { 158 159 [ResourceConsumption(ResourceScope.Process)] GetErrorString(int error)160 public static string GetErrorString(int error) 161 { 162 StringBuilder stringBuilder = new StringBuilder(512); 163 164 bool result = false; 165 if ((error & 0x0FFF0000) == 0x000E0000) 166 { 167 int formatFlags = UnsafeNativeMethods.FORMAT_MESSAGE_IGNORE_INSERTS 168 | UnsafeNativeMethods.FORMAT_MESSAGE_ARGUMENT_ARRAY 169 | UnsafeNativeMethods.FORMAT_MESSAGE_FROM_HMODULE; 170 171 result = (0 != UnsafeNativeMethods.FormatMessage( 172 formatFlags, 173 Msmq.ErrorStrings, 174 error, 175 CultureInfo.CurrentCulture.LCID, 176 stringBuilder, 177 stringBuilder.Capacity, 178 IntPtr.Zero)); 179 } 180 else 181 { 182 int formatFlags = UnsafeNativeMethods.FORMAT_MESSAGE_IGNORE_INSERTS 183 | UnsafeNativeMethods.FORMAT_MESSAGE_ARGUMENT_ARRAY 184 | UnsafeNativeMethods.FORMAT_MESSAGE_FROM_SYSTEM; 185 186 result = (0 != UnsafeNativeMethods.FormatMessage( 187 formatFlags, 188 IntPtr.Zero, 189 error, 190 CultureInfo.CurrentCulture.LCID, 191 stringBuilder, 192 stringBuilder.Capacity, 193 IntPtr.Zero)); 194 } 195 196 if (result) 197 { 198 stringBuilder = stringBuilder.Replace("\n", ""); 199 stringBuilder = stringBuilder.Replace("\r", ""); 200 return SR.GetString( 201 SR.MsmqKnownWin32Error, 202 stringBuilder.ToString(), 203 error.ToString(CultureInfo.InvariantCulture), 204 Convert.ToString(error, 16)); 205 } 206 else 207 { 208 return SR.GetString( 209 SR.MsmqUnknownWin32Error, 210 error.ToString(CultureInfo.InvariantCulture), 211 Convert.ToString(error, 16)); 212 } 213 } 214 } 215 } 216 217