internal static void UpdateSubmissionExceptionStatisticRecords(MessageStatus messageStatus, int lastOccurrencesPerException, int callstacksPerBucket, MailItemSubmitter mailItemSubmitter) { MapiSubmissionInfo mapiSubmissionInfo = mailItemSubmitter.SubmissionInfo as MapiSubmissionInfo; StoreDriverSubmission.SubmissionOccurrenceRecord submissionOccurrenceRecord = new StoreDriverSubmission.SubmissionOccurrenceRecord(DateTime.UtcNow, mailItemSubmitter.StartTime, mailItemSubmitter.SubmissionInfo.MdbGuid, (mapiSubmissionInfo == null) ? Guid.Empty : mapiSubmissionInfo.MailboxGuid, (mapiSubmissionInfo == null) ? null : mapiSubmissionInfo.EntryId, (mapiSubmissionInfo == null) ? null : mapiSubmissionInfo.ParentEntryId, (mapiSubmissionInfo == null) ? 0L : mapiSubmissionInfo.EventCounter, mailItemSubmitter.OrganizationId, mailItemSubmitter.ErrorCode, mailItemSubmitter.SubmissionInfo.MailboxFqdn, mailItemSubmitter.Item.HasMessageItem ? mailItemSubmitter.Item.Item.InternetMessageId : null, mailItemSubmitter.SubmissionConnectionId, mailItemSubmitter.MessageSize, mailItemSubmitter.RecipientCount, mailItemSubmitter.Result.Sender, mailItemSubmitter.Stage); if (lastOccurrencesPerException > 0) { string key = StoreDriverSubmission.GenerateExceptionKey(messageStatus); lock (StoreDriverSubmission.submissionExceptionStatisticRecords) { StoreDriverSubmission.ExceptionStatisticRecord <StoreDriverSubmission.SubmissionOccurrenceRecord> value; if (!StoreDriverSubmission.submissionExceptionStatisticRecords.TryGetValue(key, out value)) { value = default(StoreDriverSubmission.ExceptionStatisticRecord <StoreDriverSubmission.SubmissionOccurrenceRecord>); value.LastOccurrences = new Queue <StoreDriverSubmission.SubmissionOccurrenceRecord>(lastOccurrencesPerException); } if (value.LastOccurrences.Count == lastOccurrencesPerException) { value.LastOccurrences.Dequeue(); } value.LastOccurrences.Enqueue(submissionOccurrenceRecord); value.CountSinceServiceStart++; StoreDriverSubmission.submissionExceptionStatisticRecords[key] = value; } } StoreDriverSubmission.UpdateSubmissionExceptionCallstackRecords(messageStatus, callstacksPerBucket, submissionOccurrenceRecord); }
public bool GetQuarantineInfoContext(Guid resourceGuid, TimeSpan quarantineExpiryWindow, out QuarantineInfoContext quarantineInfoContext) { ArgumentValidator.ThrowIfEmpty("resourceGuid", resourceGuid); quarantineInfoContext = null; bool result; try { string text = resourceGuid.ToString(); using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(string.Format(RegistryCrashRepository.resourceSubKeyFromRoot, this.poisonRegistryEntryLocation, text), RegistryKeyPermissionCheck.ReadWriteSubTree)) { DateTime quarantineStartTime; if (registryKey != null && this.GetQuarantineStartTime(registryKey, text, quarantineExpiryWindow, out quarantineStartTime)) { quarantineInfoContext = new QuarantineInfoContext(quarantineStartTime); return(true); } } result = false; } catch (UnauthorizedAccessException ex) { StoreDriverSubmission.LogEvent(MSExchangeStoreDriverSubmissionEventLogConstants.Tuple_PoisonMessageLoadFailedRegistryAccessDenied, null, new object[] { ex.Message }); throw new CrashRepositoryAccessException(Strings.PoisonMessageRegistryAccessFailed, ex); } return(result); }
internal static void RecordExceptionForDiagnostics(MessageStatus messageStatus, IMessageConverter messageConverter) { if (messageStatus.Exception != null && (messageStatus.Action == MessageAction.NDR || messageStatus.Action == MessageAction.Retry || messageStatus.Action == MessageAction.RetryQueue || messageStatus.Action == MessageAction.Reroute || messageStatus.Action == MessageAction.RetryMailboxServer || messageStatus.Action == MessageAction.Skip) && messageConverter.IsOutbound) { StoreDriverSubmission.UpdateSubmissionExceptionStatisticRecords(messageStatus, Components.TransportAppConfig.MapiSubmission.MaxStoreDriverSubmissionExceptionOccurrenceHistoryPerException, Components.Configuration.AppConfig.MapiSubmission.MaxStoreDriverSubmissionExceptionCallstackHistoryPerBucket, (MailItemSubmitter)messageConverter); } }
public void Start(bool initiallyPaused, ServiceState targetRunningState) { lock (this.syncObject) { this.paused = initiallyPaused; ADNotificationAdapter.RunADOperation(delegate() { try { StoreDriverSubmission.localIp = Dns.GetHostEntry(Dns.GetHostName()); } catch (SocketException ex) { this.storeDriverTracer.StoreDriverSubmissionTracer.TraceFail <string>(this.storeDriverTracer.MessageProbeActivityId, 0L, "Start failed: {0}", ex.ToString()); StoreDriverSubmission.LogEvent(MSExchangeStoreDriverSubmissionEventLogConstants.Tuple_StoreDriverSubmissionGetLocalIPFailure, null, new object[] { ex }); throw new TransportComponentLoadFailedException(ex.Message, ex); } StoreDriverSubmission.receivedHeaderTcpInfo = StoreDriverSubmission.FormatIPAddress(StoreDriverSubmission.localIp.AddressList[0]); this.storeDriverTracer.StoreDriverSubmissionTracer.TracePass(this.storeDriverTracer.MessageProbeActivityId, 0L, "Start submission"); this.StartSubmission(); }, 1); } }
public void PurgeResourceData(Guid resourceGuid) { ArgumentValidator.ThrowIfEmpty("resourceGuid", resourceGuid); try { using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(this.poisonRegistryEntryLocation, RegistryKeyPermissionCheck.ReadWriteSubTree)) { if (registryKey != null) { using (RegistryKey registryKey2 = registryKey.OpenSubKey(resourceGuid.ToString())) { if (registryKey2 != null && registryKey2.GetValueNames().Length == 0) { registryKey.DeleteSubKeyTree(resourceGuid.ToString(), false); } } } } } catch (UnauthorizedAccessException ex) { StoreDriverSubmission.LogEvent(MSExchangeStoreDriverSubmissionEventLogConstants.Tuple_PoisonMessageSaveFailedRegistryAccessDenied, null, new object[] { ex.Message }); throw new CrashRepositoryAccessException(Strings.PoisonMessageRegistryAccessFailed, ex); } }
public bool PersistQuarantineInfo(Guid resourceGuid, QuarantineInfoContext quarantineInfoContext, bool overrideExisting = false) { ArgumentValidator.ThrowIfEmpty("resourceGuid", resourceGuid); ArgumentValidator.ThrowIfNull("quarantineInfoContext", quarantineInfoContext); try { using (RegistryKey registryKey = Registry.LocalMachine.CreateSubKey(this.poisonRegistryEntryLocation + "\\" + resourceGuid.ToString())) { if (registryKey.GetValue("QuarantineStart") == null || overrideExisting) { registryKey.SetValue("QuarantineStart", quarantineInfoContext.QuarantineStartTime); return(true); } } } catch (UnauthorizedAccessException ex) { StoreDriverSubmission.LogEvent(MSExchangeStoreDriverSubmissionEventLogConstants.Tuple_PoisonMessageSaveFailedRegistryAccessDenied, null, new object[] { ex.Message }); throw new CrashRepositoryAccessException(Strings.PoisonMessageRegistryAccessFailed, ex); } return(false); }
public void Unload() { lock (this.syncObject) { ProcessAccessManager.UnregisterComponent(this); } MExEvents.Shutdown(); StoreDriverSubmission.ShutdownPerformanceCounterMaintenance(); }
private void LogEvent(ExEventLog.EventTuple eventTuple) { StoreDriverSubmission.LogEvent(eventTuple, null, new object[] { this.EventCounter, this.MailboxGuid, base.MdbGuid }); }
public bool GetResourceCrashInfoData(Guid resourceGuid, TimeSpan crashExpiryWindow, out Dictionary <long, ResourceEventCounterCrashInfo> resourceCrashData, out SortedSet <DateTime> allCrashTimes) { ArgumentValidator.ThrowIfEmpty("resourceGuid", resourceGuid); string text = resourceGuid.ToString(); resourceCrashData = new Dictionary <long, ResourceEventCounterCrashInfo>(); allCrashTimes = new SortedSet <DateTime>(); try { using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(string.Format(RegistryCrashRepository.poisonInfoKeyLocationFromRoot, this.poisonRegistryEntryLocation, text), RegistryKeyPermissionCheck.ReadWriteSubTree)) { if (registryKey != null) { foreach (string text2 in registryKey.GetValueNames()) { if (string.IsNullOrEmpty(text2)) { registryKey.DeleteValue(text2, false); } else { ResourceEventCounterCrashInfo resourceEventCounterCrashInfo = null; long num; if (this.ProcessEventCounterData(text2, registryKey, text, out num)) { string[] eventCounterCrashInfo = null; if (this.GetEventCounterCrashInfoValue(text2, registryKey, text, out eventCounterCrashInfo) && this.ProcessSingleEventCounterCrashInfoValue(eventCounterCrashInfo, text2, registryKey, text, crashExpiryWindow, out resourceEventCounterCrashInfo)) { resourceCrashData.Add(num, resourceEventCounterCrashInfo); allCrashTimes.UnionWith(resourceEventCounterCrashInfo.CrashTimes); this.AddDataToPurgeDictionary(resourceGuid, num, resourceEventCounterCrashInfo.CrashTimes.Max); } } } } } } } catch (UnauthorizedAccessException ex) { StoreDriverSubmission.LogEvent(MSExchangeStoreDriverSubmissionEventLogConstants.Tuple_PoisonMessageLoadFailedRegistryAccessDenied, null, new object[] { ex.Message }); throw new CrashRepositoryAccessException(Strings.PoisonMessageRegistryAccessFailed, ex); } return(resourceCrashData.Count != 0); }
private void StartSubmission() { try { ProcessAccessManager.RegisterComponent(this); } catch (Exception ex) { this.storeDriverTracer.StoreDriverSubmissionTracer.TraceFail <string>(this.storeDriverTracer.MessageProbeActivityId, 0L, "Failed to start Store Driver Submission: {0}", ex.ToString()); StoreDriverSubmission.LogEvent(MSExchangeStoreDriverSubmissionEventLogConstants.Tuple_StoreDriverSubmissionStartFailure, null, new object[] { ex }); throw new TransportComponentLoadFailedException(ex.Message, ex); } }
public void BeginSubmission(ulong id, string server, string database) { int num = Interlocked.Increment(ref SubmissionThreadLimiter.concurrentSubmissions); if (num > Components.Configuration.LocalServer.MaxConcurrentMailboxSubmissions) { StoreDriverSubmission.LogEvent(MSExchangeStoreDriverSubmissionEventLogConstants.Tuple_TooManySubmissionThreads, null, new object[] { Components.Configuration.LocalServer.MaxConcurrentMailboxSubmissions }); string message = string.Format("Total thread count exceeded limit of {0} threads.", Components.Configuration.LocalServer.MaxConcurrentMailboxSubmissions); throw new ThreadLimitExceededException(message); } if (SubmissionThreadLimiter.databaseThreadMap.ThreadLimit > 0) { SubmissionThreadLimiter.databaseThreadMap.CheckAndIncrement(database, id, database); this.databaseThreadMapEntry = database; } }
XElement IDiagnosable.GetDiagnosticInfo(DiagnosableParameters parameters) { bool flag = parameters.Argument.IndexOf("exceptions", StringComparison.OrdinalIgnoreCase) != -1; bool flag2 = parameters.Argument.IndexOf("callstacks", StringComparison.OrdinalIgnoreCase) != -1; bool flag3 = parameters.Argument.IndexOf("verbose", StringComparison.OrdinalIgnoreCase) != -1; bool flag4 = flag3 || parameters.Argument.IndexOf("basic", StringComparison.OrdinalIgnoreCase) != -1; bool flag5 = parameters.Argument.IndexOf("currentThreads", StringComparison.OrdinalIgnoreCase) != -1; bool flag6 = flag4 || parameters.Argument.IndexOf("config", StringComparison.OrdinalIgnoreCase) != -1; bool flag7 = !flag6 || parameters.Argument.IndexOf("help", StringComparison.OrdinalIgnoreCase) != -1; XElement xelement = new XElement(((IDiagnosable)this).GetDiagnosticComponentName()); if (flag7) { xelement.Add(new XElement("help", "Supported arguments: config, basic, verbose, exceptions, callstacks, currentThreads, help.")); } if (flag6) { SubmissionConfiguration.Instance.App.AddDiagnosticInfo(xelement); } if (flag4) { xelement.Add(new XElement("submittingThreads", SubmissionThreadLimiter.ConcurrentSubmissions)); xelement.Add(SubmissionThreadLimiter.DatabaseThreadMap.GetDiagnosticInfo(new XElement("SubmissionDatabaseThreadMap"))); } if (flag5 && this.SubmissionsInProgress != null) { xelement.Add(this.SubmissionsInProgress.GetDiagnosticInfo()); } if (flag3) { xelement.Add(MailItemSubmitter.GetDiagnosticInfo()); } if (flag) { StoreDriverSubmission.DumpExceptionStatistics(xelement); } if (flag2) { StoreDriverSubmission.DumpExceptionCallstacks(xelement); } return(xelement); }
public void PersistCrashInfo(Guid resourceGuid, long eventCounter, ResourceEventCounterCrashInfo resourceEventCounterCrashInfo, int maxCrashEntries) { ArgumentValidator.ThrowIfEmpty("resourceGuid", resourceGuid); ArgumentValidator.ThrowIfNull("resourceEventCounterCrashInfo", resourceEventCounterCrashInfo); ArgumentValidator.ThrowIfZeroOrNegative("maxCrashEntries", maxCrashEntries); try { using (RegistryKey registryKey = Registry.LocalMachine.CreateSubKey(string.Format(RegistryCrashRepository.poisonInfoKeyLocationFromRoot, this.poisonRegistryEntryLocation, resourceGuid))) { this.PersistCrashInfoToRegistry(registryKey, resourceGuid, eventCounter, resourceEventCounterCrashInfo, maxCrashEntries); } } catch (UnauthorizedAccessException ex) { StoreDriverSubmission.LogEvent(MSExchangeStoreDriverSubmissionEventLogConstants.Tuple_PoisonMessageSaveFailedRegistryAccessDenied, null, new object[] { ex.Message }); throw new CrashRepositoryAccessException(Strings.PoisonMessageRegistryAccessFailed, ex); } }
public void Load() { lock (this.syncObject) { ProcessAccessManager.RegisterComponent(this); } try { MExEvents.Initialize(Path.Combine(ConfigurationContext.Setup.InstallPath, "TransportRoles\\Shared\\agents.config"), ProcessTransportRole.MailboxSubmission, LatencyAgentGroup.MailboxTransportSubmissionStoreDriverSubmission, "Microsoft.Exchange.Data.Transport.StoreDriver.StoreDriverAgent"); StoreDriverSubmission.InitializePerformanceCounterMaintenance(); } catch (ExchangeConfigurationException ex) { this.storeDriverTracer.StoreDriverSubmissionTracer.TraceFail(this.storeDriverTracer.MessageProbeActivityId, (long)this.GetHashCode(), "StoreDriversubmission.Load threw ExchangeConfigurationException: shutting down service."); StoreDriverSubmission.LogEvent(MSExchangeStoreDriverSubmissionEventLogConstants.Tuple_CannotStartAgents, null, new object[] { ex.LocalizedString, ex }); this.Stop(); } }
public List <Guid> GetAllResourceIDs() { List <Guid> list = new List <Guid>(); List <Guid> result; try { using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(this.poisonRegistryEntryLocation, RegistryKeyPermissionCheck.ReadWriteSubTree)) { if (registryKey != null) { foreach (string text in registryKey.GetSubKeyNames()) { Guid item; if (!Guid.TryParse(text, out item)) { this.storeDriverTracer.GeneralTracer.TraceFail <string>(this.storeDriverTracer.MessageProbeActivityId, 0L, "Invalid Resource Guid {0}. Deleting it.", text); registryKey.DeleteSubKeyTree(text); } else { list.Add(item); } } } } result = list; } catch (UnauthorizedAccessException ex) { StoreDriverSubmission.LogEvent(MSExchangeStoreDriverSubmissionEventLogConstants.Tuple_PoisonMessageLoadFailedRegistryAccessDenied, null, new object[] { ex.Message }); throw new CrashRepositoryAccessException(Strings.PoisonMessageRegistryAccessFailed, ex); } return(result); }
private MailSubmissionResult SubmitMessageImpl(MapiSubmissionInfo submissionInfo, SubmissionPoisonHandler submissionPoisonHandler, QuarantineHandler quarantineHandler) { MailSubmissionResult mailSubmissionResult = new MailSubmissionResult(); if (this.Retired) { mailSubmissionResult.ErrorCode = 2214592514U; return(mailSubmissionResult); } string mailboxFqdn = submissionInfo.MailboxFqdn; string database = submissionInfo.MdbGuid.ToString(); MailSubmissionResult result; using (submissionInfo.GetTraceFilter()) { using (SubmissionConnectionWrapper connection = SubmissionConnectionPool.GetConnection(mailboxFqdn, database)) { using (SubmissionThreadLimiter submissionThreadLimiter = new SubmissionThreadLimiter()) { SubmissionPoisonContext submissionPoisonContext = null; try { submissionThreadLimiter.BeginSubmission(connection.Id, mailboxFqdn, database); if (this.Retired) { mailSubmissionResult.ErrorCode = 2214592514U; connection.SubmissionAborted("Retiring."); result = mailSubmissionResult; } else { this.storeDriverTracer.StoreDriverSubmissionTracer.TracePfdPass <int, MapiSubmissionInfo>(this.storeDriverTracer.MessageProbeActivityId, 0L, "PFD ESD {0} Processing SubmitMessage for {1}", 27547, submissionInfo); submissionPoisonContext = submissionInfo.GetPoisonContext(); MailItemSubmitter mailItemSubmitter2; MailItemSubmitter mailItemSubmitter = mailItemSubmitter2 = new MailItemSubmitter(connection.Id, submissionInfo, this.sendAsManager, submissionPoisonHandler, submissionPoisonContext, this); try { QuarantineInfoContext quarantineInfoContext; TimeSpan timeSpan; if (SubmissionConfiguration.Instance.App.EnableMailboxQuarantine && quarantineHandler.IsResourceQuarantined(submissionPoisonContext.ResourceGuid, out quarantineInfoContext, out timeSpan)) { mailSubmissionResult.ErrorCode = 1140850696U; mailSubmissionResult.QuarantineTimeSpan = timeSpan; mailSubmissionResult.DiagnosticInfo = string.Format("{0}:{1}, QuarantineRemainingTimeSpan:{2}", "QuarantineStart", quarantineInfoContext.QuarantineStartTime, timeSpan); connection.SubmissionFailed(string.Format("Resource {0} is in quarantined state", submissionPoisonContext.ResourceGuid)); return(mailSubmissionResult); } if (this.PoisonMessageDectionEnabled && submissionPoisonHandler.VerifyPoisonMessage(submissionPoisonContext)) { this.LogPoisonMessageMTL(submissionInfo, submissionPoisonContext); if (SubmissionConfiguration.Instance.App.EnableSendNdrForPoisonMessage) { if (!submissionPoisonHandler.VerifyPoisonNdrSent(submissionPoisonContext)) { mailItemSubmitter.HandlePoisonMessageNdrSubmission(); mailSubmissionResult.ErrorCode = StoreDriverSubmissionUtils.MapSubmissionStatusErrorCodeToPoisonErrorCode(mailItemSubmitter.Result.ErrorCode); } } else { mailSubmissionResult.ErrorCode = 3U; } connection.SubmissionAborted(string.Format("Poison Context Info: Resource = {0};EventCounter = {1}.", submissionPoisonContext.ResourceGuid, submissionPoisonContext.MapiEventCounter)); return(mailSubmissionResult); } Thread currentThread = Thread.CurrentThread; try { this.SubmissionsInProgress[currentThread] = mailItemSubmitter; mailItemSubmitter.Submit(); mailSubmissionResult.RemoteHostName = mailItemSubmitter.Result.RemoteHostName; } finally { this.SubmissionsInProgress.Remove(currentThread); } } finally { if (mailItemSubmitter2 != null) { ((IDisposable)mailItemSubmitter2).Dispose(); } } if (mailItemSubmitter.Result.ErrorCode == 0U) { connection.SubmissionSuccessful(mailItemSubmitter.MessageSize, mailItemSubmitter.RecipientCount); } else { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("HResult: "); stringBuilder.Append(mailItemSubmitter.Result.ErrorCode.ToString()); stringBuilder.Append("; DiagnosticInfo: "); stringBuilder.Append(mailItemSubmitter.Result.DiagnosticInfo); connection.SubmissionFailed(stringBuilder.ToString()); } if (mailItemSubmitter.Result.ErrorCode == 3U) { submissionInfo.LogEvent(SubmissionInfo.Event.StoreDriverSubmissionPoisonMessageInSubmission); } result = mailItemSubmitter.Result; } } catch (ThreadLimitExceededException ex) { connection.SubmissionAborted(ex.Message); mailSubmissionResult.ErrorCode = 1090519042U; mailSubmissionResult.DiagnosticInfo = ex.Message; result = mailSubmissionResult; } catch (Exception exception) { try { submissionPoisonHandler.SavePoisonContext(submissionPoisonContext); string exceptionDiagnosticInfo = StorageExceptionHandler.GetExceptionDiagnosticInfo(exception); connection.SubmissionFailed("Exception: " + exceptionDiagnosticInfo); submissionInfo.LogEvent(SubmissionInfo.Event.StoreDriverSubmissionPoisonMessage, exception); FailFast.Fail(exception); } catch (Exception ex2) { StoreDriverSubmission.LogEvent(MSExchangeStoreDriverSubmissionEventLogConstants.Tuple_StoreDriverSubmissionFailFastFailure, null, new object[] { ex2 }); } result = mailSubmissionResult; } } } } return(result); }