Пример #1
0
		internal bool ExecuteSendLinkAction(IProxy mailItem, RequestManager requestManager)
		{
            throw new NotImplementedException("SendLink is not supported for Lotus Notes");
            //Interop.Logging.Logger.LogInfo("Executing Send Link Process");
            //try
            //{
            //    Attachment[] processedAttachments = requestManager.EnforceResponse.ModifiedRequest.Attachments;
            //    if (processedAttachments.Length == 0)
            //    {
            //        Interop.Logging.Logger.LogInfo("No files to upload");
            //        return true;
            //    }

            //    string id = Guid.NewGuid().ToString();
            //    List<SendLinkInfo> filesToUpload = GetFilesToUpload(processedAttachments, id);
            //    List<string> emailAddresses = GetRecipientAddressList(mailItem);
            //    string subject = ConvertLineFeed2WhiteSpace(mailItem.GetSubject()).TrimEnd();

            //    // Upload to the cloud
            //    var sendLinkAction = GetSendLinkAction(requestManager.Response);
            //    var storageLinks = GetStorageLinks(requestManager.Response, sendLinkAction);
            //    storageLinks.Authenticate();
            //    List<SendLinkInfo> filesUploaded = RetrieveLinks(storageLinks, sendLinkAction, requestManager.Response, filesToUpload, emailAddresses, subject, id);

            //    // Update proxy for Notes extension manager
            //    UpdateProxyForSendLink(mailItem, GetSendLinkText(), filesUploaded, id);

            //    return true;
            //}
            //catch (StorageUnavailableException ex)
            //{
            //    // note, the class name for Notes window is SWT_Window0 however class name is not unique to notes (most SWT framework apps will have this class name)
            //    WsMessage.ShowMessage(IntPtr.Zero, Resources.PleaseCheckYourInternetConnection, MessageButtons.WsOK, MessageBranding.WsProtect,
            //                             MessageType.WsErrorIcon, Resources.UnableToConnectToSendLink, -1);
            //    throw new AbortSendLinkException(ex.Message);
            //}
            //catch (Exception e)
            //{
            //    Interop.Logging.Logger.LogError(e);
            //    throw;
            //}
		}
Пример #2
0
		private void RemoveNonBccWhiteListRecipientsFromDestinationItems(MailItem mailItem, RequestManager requestManager)
		{
			var bccList = BccWhiteList.GetBCCList(mailItem.BCC);

			var items = requestManager.EnforceResponse.ModifiedRequest.Destination.Items
			   .Where(it => !it.Properties.Any(p => string.Equals(p.Name, "AddressType", StringComparison.InvariantCulture) && string.Equals(p.Value, "BCC", StringComparison.InvariantCulture))
							 || bccList.Any(adress => string.Equals(adress, it.Content)))
			   .Select(i => i).ToArray();


			requestManager.EnforceResponse.ModifiedRequest.Destination.Items = items;
		}
Пример #3
0
		internal bool CreateListOfAttachmentsToSendLink(MailItem mailItem, PolicyContent.Attachment[] builtup, RequestManager requestManager, ref List<PolicyContent.Attachment> listAttachments)
		{
			Logger.LogInfo("Matching the original attachments with the rebuilt collection and returning a list of items to SendLink");

			// ensure we have Recordkey of each non-signature attachment
			MessageBodyFormat bodyFormat;
		
            if (UseOutlookDOMForProcessing)
            {
                using (OutlookMailProxy outlookMailProxy = new OutlookMailProxy(mailItem))
                {
                    bodyFormat = OutlookBodyFormat.GetMessageBodyFormat(outlookMailProxy.FormattedBodyText);
                    Logger.LogInfo("Email body format: " + bodyFormat.ToString());
                }
            }
            else
            {
                using (RedemptionMailProxy redemptionMailProxy = new RedemptionMailProxy(mailItem, true, DisableAccessToDOMAttachments))
                {
                    bodyFormat = OutlookBodyFormat.GetMessageBodyFormat(redemptionMailProxy.FormattedBodyText);
                    Logger.LogInfo("Email body format: " + bodyFormat.ToString());
                }
            }


			List<string> recordKeys = new List<string>(GetListofRecordKeys(mailItem, bodyFormat));
			if (recordKeys.Count <= 0)
			{
				Logger.LogDebug("The list of record keys for the email is empty. Assuming the email only contains a signature image so there's nothing to SendLink.");
				return true;
			}

			foreach (PolicyContent.Attachment attachment in builtup)
			{
				// .msg files are flattened before normal Protect processing, so they need to be treated as
				// a special case as their IDs won't match against the processed file list.
				// i.e. att.Id == attachment.Id will not work (see below).
				if (!String.IsNullOrEmpty(attachment.FileName) && attachment.FileName.EndsWith(".msg", StringComparison.InvariantCultureIgnoreCase))
				{
					CustomProperty[] properties = attachment.Properties;
					bool hasRecordKey = false;

					// .msg files should always have a RecordKey, but check anyway for error cases     
					foreach (CustomProperty cp in properties)
					{
						hasRecordKey = (cp.Name == "RecordKey") && (recordKeys.Contains(cp.Value));

						if (hasRecordKey)
						{
							listAttachments.Add(attachment);
							Logger.LogInfo(".msg file added to SendLink attachments list.  Backing file: " + attachment.FileName);
							break;
						}
					}

					if (!hasRecordKey)
					{
						Logger.LogError("RecordKey was not found in the attachment's custom properties when processing .msg: " + attachment.FileName);
						return false;
					}
				}
				else
				{
					foreach (PolicyContent.Attachment att in requestManager.Request.Attachments)
					{
						// Match attachment on mailItem with processed equivalent in builtup collection
						// and add to SendLink list
						if (att.Id == attachment.Id)
						{
							CustomProperty[] properties = att.Properties;
							bool hasRecordKey = false;

							foreach (CustomProperty cp in properties)
							{
								hasRecordKey = (cp.Name == "RecordKey") && (recordKeys.Contains(cp.Value));

								// we don't want signature images
								if (hasRecordKey)
								{
									if ((attachment.Properties == null) || (attachment.Properties.Length == 0))
									{
										attachment.Properties = new[] { cp };
									}

									listAttachments.Add(attachment);
									break;
								}
							}

							if (!hasRecordKey)
							{
								Logger.LogDebug("Unable to find a RecordKey for attachment.  Assuming this is a signature image: " + attachment.Name);
							}
							break;
						}
					}
				}
			}

			return true;
		}
Пример #4
0
		internal bool ExecuteSendLinkAction(MailItem mailItem, PolicyContent.Attachment[] builtup, RequestManager requestManager)
		{
			Logger.LogInfo("Executing Secure File Transfer Process");

            Workshare.Analytics.WsAnalyticsListener analyticsListener = new Workshare.Analytics.WsAnalyticsListener();
            analyticsListener.SendSendLinkStatistic();

			if (!requestManager.SendAndProtect && !ShowBccWarning(mailItem, requestManager))
            {
                return false;
            }

            try
            {
                List<PolicyContent.Attachment> listAttachments = new List<PolicyContent.Attachment>();

                if (!CreateListOfAttachmentsToSendLink(mailItem, builtup, requestManager, ref listAttachments))
                {
                    return false;
                }

        
                if (listAttachments.Count <= 0)
                {
                    Logger.LogInfo("List of attachments to SendLink is empty");
                    return true;
                }
                string id = Guid.NewGuid().ToString();
                List<SendLinkInfo> links = GetLinks(requestManager.Response, mailItem, listAttachments, id);
             


                if (links != null && links.Count > 0)
                {
					Logger.LogInfo("Secure File Transfer: removing old attachments");

                    //SetMessageWindowVisible(mailItem, false);

                    //This call will change the mailItem
                    AdjustAttachments(mailItem, links, id);


                    if (!string.IsNullOrEmpty(GetPropertyValue(requestManager.EnforceResponse.ModifiedRequest.Properties,
                                                               MailMessagePropertyKeys.MimeContent)) ||
                        !string.IsNullOrEmpty(GetPropertyValue(requestManager.EnforceResponse.ModifiedRequest.Properties,
                                                               MailMessagePropertyKeys.LargeMimeContent)))
                    {
                        string body;
                        // Need to create a new proxy object because mailItem was changed in AdjustAttachments()
                        if (UseOutlookDOMForProcessing)
                        {
                            using (OutlookMailProxy outlookMailProxy = new OutlookMailProxy(mailItem))
                            {
                                body = outlookMailProxy.FormattedBodyText;
                                body = OutlookFormattedTextProcessor.NewFormattedBodyText(body, links, mailItem);
                            }
                        }
                        else
                        {
                            using (RedemptionMailProxy redemptionMailProxy = new RedemptionMailProxy(mailItem, true, DisableAccessToDOMAttachments))
                            {
                                body = redemptionMailProxy.FormattedBodyText;
                                body = OutlookFormattedTextProcessor.NewFormattedBodyText(body, links, mailItem, false);

                                //private static void InsertHtmlIntoBodyText(ref string body, MessageBodyFormat bodyformat, IEnumerable<SendLinkInfo> links, MailItem mailItem)
                                //sets body as null.
                                if (body != null)
                                {
                                    redemptionMailProxy.FormattedBodyText = body;
                                }
                            }
                        }

                        if (body != null)
                        {
                            SetPropertyValue(requestManager.EnforceResponse.ModifiedRequest.Properties, MailMessagePropertyKeys.FormattedBody, body);
                        }
                    }

					Logger.LogInfo("End Secure File Transfer Process");

                    // Allow the inspector window to redraw now, so that the attachments
                    // and altered body text are immediately updated.
                    System.Windows.Forms.Application.DoEvents();
                }
                else
                {
                    Logger.LogInfo("No Links to process");
                }

                StartSendLinkClient();

                mailItem.UserProperties.Add("SendLink", OlUserPropertyType.olText);
            }
            catch (Exception e)
            {
                //SetMessageWindowVisible(mailItem, true);
                Logger.LogError(e);
                throw;
            }

            return true;
		}
Пример #5
0
        public bool ShowBccWarning(MailItem mailItem, RequestManager requestManager = null)
        {
            // check that the email's BCC doesn't contain any recipients other than
            // those specified in the BccAddressesWhiteList option list.
            if (!string.IsNullOrEmpty(mailItem.BCC))
            {
                Logger.LogInfo("Email has BCC recipients");

                if (!BccWhiteList.BccContainsWhiteListAddresses(mailItem.BCC))
                {
                    if (string.IsNullOrEmpty(mailItem.To) && string.IsNullOrEmpty(mailItem.CC))
                    {
                        Interop.Messaging.WsMessage.ShowMessage(IntPtr.Zero,
                                                                Resources.SENDLINK_MSG_HAS_ONLY_BCC,
                                                                Interop.Messaging.MessageButtons.WsOK,
                                                                Interop.Messaging.MessageBranding.WsDefault,
                                                                Interop.Messaging.MessageType.WsInfoIcon,
                                                                Resources.SENDLINK_MSG_HAS_BCC_HEADLINE,
                                                                -1);
                        return false;
                    }
                }

                if (!BccWhiteList.ContainsOnlyWhiteListedAddresses(mailItem.BCC))
                {
                    if (Interop.Messaging.WsMessage.ShowMessage(
                        IntPtr.Zero,
                        Resources.SENDLINK_MSG_HAS_BCC,
                        Interop.Messaging.MessageButtons.WsOKCancel,
                        Interop.Messaging.MessageBranding.WsDefault,
                        Interop.Messaging.MessageType.WsInfoIcon,
                        Resources.SENDLINK_MSG_HAS_BCC_HEADLINE,
                        -1)
                        == Interop.Messaging.MessageResult.WsResultCancel)
                    {
                        return false;
                    }
                    Logger.LogInfo("Removing all non-white list BCC recipients");
                    mailItem.BCC = BccWhiteList.RemoveNonBccWhiteListRecipients(mailItem.BCC);

                    if (requestManager != null)
                    {
                        RemoveNonBccWhiteListRecipientsFromDestinationItems(mailItem, requestManager);
                    }
                }
            }
            return true;
        }
Пример #6
0
		private void OnItemSend(IProxy mailItem, ref bool cancelEmailSend, ref ProcessResult processResult)
		{
			RequestManager requestManager = null;
			try
			{
				InitClientProgress();

				PolicyContent.Request request = CreateRequest(mailItem);

                List<PolicyContent.Attachment> attachmentsNotProcessed = new List<PolicyContent.Attachment>();
                // Remove the msg top level attachments from the request. We need to add them back after processing before updating the Notes proxy.
                // We do this because msg files are being lost in processing (ActionExecuter.RecreateAttachments)but since they are not supported 
                // file types in Notes we can remove them from the attachment collection to be processed and add them back later after the call to 
                // ProcessRequest. This does not affect msg files in zip containers and those are not lost.
                attachmentsNotProcessed.AddRange(ExtractAttachmentsOfTypeEmail(request));                

				bool bInternal = true;
				foreach (PolicyContent.RoutingItem rItem in request.Destination.Items)
				{
					foreach (PolicyContent.CustomProperty cProperty in rItem.Properties)
					{
						if ((cProperty.Name.ToLower(CultureInfo.InvariantCulture) == "internal") && (cProperty.Value.ToLower(CultureInfo.InvariantCulture) == "false"))
						{
							bInternal = false;
							break;
						}
					}
					if (!bInternal)
						break;
				}

                requestManager = new RequestManager(request, new NotesUIManager());
            	requestManager.MailItem = mailItem;
				requestManager.IsLotusNotesMailClient = true;

				bool bApplyPolicy = true;
				if (bInternal)
				{
					bApplyPolicy = Interop.Options.OptionApi.GetBool("EmailApplyProtectPolicyInternally");
				}
				else
				{
                    bApplyPolicy = Interop.Options.OptionApi.GetBool("EmailApplyProtectPolicyExternally");
				}

				if (!bApplyPolicy)
				{
					cancelEmailSend = false;
				}
				else
				{
					bool bDisplayProgress = DisplayProgressOnMailSend(request);
                    if (OptionApi.GetBool("EnableProtectSimple"))
					{
						requestManager.ProtectSimpleProfiles = GetWorkshareProfiles(mailItem, request, true, false);
						processResult = requestManager.ProcessRequestForProtectSimple(bDisplayProgress, true);
					}
					else
					{
						processResult = requestManager.ProcessRequest(m_clientProgress, bDisplayProgress, IsDynamicDiscoveryEnabled(request));
					}

					switch (processResult)
					{
					case ProcessResult.CANCELLED:
						{
							cancelEmailSend = true;
							break;
						}
					case ProcessResult.PROCESSED:
						{
                            // If a zip does not contain any supported documents the IgnoreForWorkshareActions is set (Workshare.PolicyContent.Attachment.IgnoreForWorkshareActions) 
                            // by the encryption manager (ContentEncryptionManager.ZipNeedsProcessing). This was done to improve Protect support for large files.
                            // If the ZipNeedsProcessing property is set the attachment is removed from the response (Workshare.Policy.Adaptors.RequestAdaptor.GetURO).
                            // We need to extract ANY attachment that was marked as IgnoreForWorkshareAction from the Request attachments and append them to the ModifiedRequest attachments
                            // before updating the proxy else these attachments will be removed from the Notes mail item.
                            attachmentsNotProcessed.AddRange(GetIgnoreForWorkshareActionAttachments(requestManager.Request));

                            // Add the msg top level attachments or attachments excluded from processing (IgnoreForWorkshareActions) to the processed collection before updating the proxy
                            Workshare.PolicyContent.Attachment[] processedAttachments = requestManager.EnforceResponse.ModifiedRequest.Attachments;
                            processedAttachments = AppendMissingAttachments(attachmentsNotProcessed.ToArray(), processedAttachments);
                            DeleteProxyAttachments(mailItem, processedAttachments);

                            // Not supported for Lotus Notes
							//if (SendLinkBase.ShouldExecuteSendLinkAction(requestManager.Response))
                            //{
                            //    var notesSendLink = new NotesSendLink();
                            //    cancelEmailSend = !notesSendLink.ExecuteSendLinkAction(mailItem, requestManager);
                            //    UpdateEmailContent(mailItem, requestManager.EnforceResponse.ModifiedRequest);
                            //    break;    
                            //}

                            UpdateProxyAttachments(mailItem, processedAttachments);
							UpdateEmailContent(mailItem, requestManager.EnforceResponse.ModifiedRequest);
							cancelEmailSend = false;
						    
							break;
						}
					case ProcessResult.ERRORS:
					case ProcessResult.EXCEPTION:
						{
							cancelEmailSend = !HandleErrors(requestManager.Errors);
							break;
						}
					//case ProcessResult.SERVER_PROFILE:
					//case ProcessResult.ERROR_OVERRIDE_USER_SELECTED_SEND:
					default:
						{
							// no violations or actions for this email - continue to send it.
							cancelEmailSend = false;
							break;
						}
					}
				}
			}
			catch (Exception ex)
			{
				cancelEmailSend = !ShouldContinueAfterException(ex);
			}
			finally
			{
				m_clientProgress.Complete();
				m_clientProgress.Close();
			}
		}
Пример #7
0
		private bool ExecuteSendLinkAction(MailItem mailItem, Attachment[] builtup, RequestManager requestManager)
		{
			try
			{               
			    Cursor.Current = Cursors.WaitCursor;

				OutlookSendLink sendLink;
				// For Office version prior to 2010 we need access properties and attachments via MAPI
                if (!UseOutlookDOMForProcessing || OutlookVersion.Convert(m_application.Version) <= OutlookVersion.Version.Outlook2007)
				{
					sendLink = new OutlookSendLinkMAPI();
				}
				else
				{
					sendLink = new OutlookSendLinkOOM();
				}

                if (IsDeterministicSendEnabled)
                {
                    var prSearchBytes = mailItem.PropertyAccessor.GetProperty(MAPIStringDefines.PR_SEARCH_KEY);
                    var prSearchKey = Convert.ToBase64String(prSearchBytes);
                    DeferredSendStore.Add(prSearchKey);
                }

				bool result = sendLink.ExecuteSendLinkAction(mailItem, builtup, requestManager);
				
				if (result && IsDeterministicSendEnabled)
				{
					sendLink.SetDeterministicSendDeferedTime(mailItem);
				}
				return result;
			}
			finally
			{
				Cursor.Current = Cursors.Default;
			}
		}
Пример #8
0
		private void OnItemSend(MailItem mailItem, bool hasLargeAttachments, ref bool cancelEmailSend)
		{
			MailClientHookBase.PreCacheEventWaitForCompletion();

			MailAttachmentTransform msgHandler = null;
		    Request request = null;
			try
			{
				InitClientProgress();

				request = CreateRequest(mailItem);
			    request.HasLargeAttachments = hasLargeAttachments;

				//WriteOutRequest(request);

                msgHandler = new MailAttachmentTransform(GetMsgNestingLevelOption(), m_application, DisableAccessToDOMAttachments);
				List<Attachment> allAttachments = msgHandler.Flatten(request);
				if (msgHandler.AtLeastOneEmail)
				{
					request.Attachments = allAttachments.ToArray();
				}

				m_uiManager.ParentHwnd = m_parentWnd;
				RequestManager requestManager = new RequestManager(request, m_uiManager, msgHandler.ExpandMSG, msgHandler.PackMSG);
				requestManager.TotalAttachmentSize = GetTotalAttachmentSize(mailItem);
				requestManager.IsSimpleMapi = IsSimpleMapi;
				requestManager.MailItem = mailItem;

				using (new WsActivationContext())
				{
					bool bDisplayProgress = DisplayProgressOnMailSend(request);

					requestManager.SendAndProtect = SendAndProtect;
				    requestManager.HasLargeAttachments = request.HasLargeAttachments;
					ProcessResult result;
					if (ProtectSimple)
					{
						bool isCorporateAccount = GetAccountType(mailItem) == MsOutlook.OlAccountType.olExchange;
                        requestManager.ProtectSimpleProfiles = GetWorkshareProfiles(mailItem.Application, request, isCorporateAccount, msgHandler.AtLeastOneEmail);
                        
                        // If any of the attachment is a large attachment, then just show send-link profiles, remove everything else
                        if (request.HasLargeAttachments)
                        {
                            int i = 0;
                            var profiles = new WorkshareProfileCollection();
                            foreach (WorkshareProfile profile in requestManager.ProtectSimpleProfiles.Values)
                            {
								if (profile.Name.Contains("Secure File Transfer"))
                                {
                                    profiles.Add(i++, profile);
                                }
                            }

                            requestManager.ProtectSimpleProfiles = profiles;
                        }
						result = requestManager.ProcessRequestForProtectSimple(bDisplayProgress, isCorporateAccount);
					}
					else
					{
						result = requestManager.ProcessRequest(m_clientProgress, bDisplayProgress, IsDynamicDiscoveryEnabled(request));
					}

					switch (result)
					{
					case ProcessResult.CANCELLED:
						cancelEmailSend = true;
						break;

					case ProcessResult.PROCESSED:
						cancelEmailSend = false;
						//////////////////////////////////////////////////////////////////////////////////////////
						// JE - 21.01.2010
						// This code block ensures that for simple attachments (i.e not containers - zip,msg)
						// we will only replace the attachment on the email if we have processed it.
						// Container atachments will currently always be replaced with rebuilt versions
						// that contain copies of the original files that may or may not have been processed.
						//////////////////////////////////////////////////////////////////////////////////////////

						Attachment[] builtup = requestManager.EnforceResponse.ModifiedRequest.Attachments;
						if (requestManager.ReplaceAllAttachments())
						{
							// This is used for the Cryptzone Secure Email Action
							// We can only support one Action that has this property and still function
							// in a reasonable fashion since we are allowing the Action to remove all 
							// attachments and replace then with completely new ones. JE 19.10.2011
							msgHandler.ReplaceAttachments(mailItem, builtup);
						}
						else
						{
							List<Attachment> processedbuiltup = requestManager.GetTopLevelProcessedAttachments();

							// VE263 Consolidate all the attachments (processed and unprocessed), so that we can recreate the email and have all the attachments in their original order.
							// Otherwise modified attachments would be added to the end of the attachment list, ie no longer in the original order.
							builtup = BuildMsgAndProcessedAttachments(msgHandler, builtup, processedbuiltup);
							if (SendLinkBase.ShouldExecuteSendLinkAction(requestManager.Response))
							{
								IsSendLink = ExecuteSendLinkAction(mailItem, builtup, requestManager);
								cancelEmailSend = !IsSendLink;
							}
							else
							{
								msgHandler.ReplaceProcessedAttachments(mailItem, builtup, requestManager.GetGroupedZipOptions());
							}
						}

						if (!cancelEmailSend)
						{
							if (IsSendLink)
							{
								SendLinkUpdateEmailContent(mailItem, requestManager.EnforceResponse.ModifiedRequest);
							}
							else
							{
								UpdateEmailContent(mailItem, requestManager.EnforceResponse.ModifiedRequest);
							}
							SetHeaderProcessingInfo(mailItem, requestManager.EnforceResponse.ModifiedRequest);
						    SetProcessedByWorkshareProtect(mailItem);

							RemoveCustomProperties(mailItem);
						}
						break;

					//VE 4955 - Don't tag the message (XHeader). Protect Server should 
					//process the message if Protect Client failed to process the message
					//and the user selected to send anyway.
					case ProcessResult.ERROR_OVERRIDE_USER_SELECTED_SEND:
						cancelEmailSend = false;
						break;

					// I presume that an Exception result is actually
					// handled by a catch block, but case added here
					// to make sure that we show an error if it isn't.
					case ProcessResult.ERRORS:
					case ProcessResult.EXCEPTION:
						cancelEmailSend = !HandleErrors(requestManager.Errors);
						break;

					default: //no violations or actions for this email - continue to send it.

                        if (request.HasLargeAttachments)
                        {
                            // and no policy triggered (probably because they are all not-supported types)
                            // then we need to replace the place-holder-files (for large attachments) with actual attachments 
                            msgHandler.ReplaceAttachments(mailItem, request.Attachments);
                        }

                        IsProtectDisabledForCurrentRouting = true;
						cancelEmailSend = false;
						SetHeaderProcessingInfo(mailItem, requestManager.Request);
					    SetProcessedByWorkshareProtect(mailItem);
						RemoveCustomProperties(mailItem);
						break;
					}
				}
			}
			catch (Exception ex)
			{
				cancelEmailSend = !ShouldContinueAfterException(ex);
			}
			finally
			{
                if (!cancelEmailSend && request != null)
                {
                    foreach (var att in request.Attachments)
                    {
                        ContentEncryptionManager.ClearPasswordCacheFor(att);
                    }
                }

				if (m_clientProgress != null)
				{
					m_clientProgress.Complete();
					m_clientProgress.Close();
				}

                if (request != null)
                {
                    request.Dispose();
                    request = null;
                }

			    // Explicitly clear up Redemption in case any extended MAPI objects are left lying around
				IWSUtilities utils = Oif.CreateUtilities();
				utils.Cleanup();

				if (msgHandler != null)
				{
					msgHandler.Dispose();
				}

				Interop.Logging.Logger.LogInfo("Shutting down application cache instance.");
				OfficeApplicationCache.Instance.ShutDown();
			}
		}