发送消息:消息存储提供程序任务

适用于:Outlook 2013 | Outlook 2016

当客户端调用消息的 IMessage::SubmitMessage 方法时,消息存储提供程序将参与消息发送过程。 如果要发送多条消息,消息存储必须按照客户端用于 SubmitMessage 调用的相同顺序发送它们。

消息存储提供程序确定是否涉及 MAPI 后台处理程序。 如果消息存储提供程序未紧密耦合,则消息需要预处理,或者紧密耦合的存储和传输无法处理所有收件人,则必须涉及 MAPI 后台处理程序。

以下过程描述了消息存储提供程序发送消息所需的任务。

在 IMessage::SubmitMessage 中,消息存储提供程序

  1. 如果消息在其PR_MESSAGE_FLAGS (PidTagMessageFlags) 属性中设置了MSGFLAG_RESEND标志,并且向客户端返回任何错误,则调用 IMAPISupport::P repareSubmitPrepareSubmit 检查邮件收件人列表中每个收件人的 PR_RECIPIENT_TYPE (PidTagRecipientType) 属性。

    • 如果设置了MAPI_SUBMITTED标志,指示收件人未收到原始邮件, PrepareSubmit 将清除该标志并将 PR_RESPONSIBILITY (PidTagResponsibility) 属性设置为 TRUE。

    • 如果未设置MAPI_SUBMITTED标志(指示收件人确实收到原始邮件), PrepareSubmit 会将 PR_RECIPIENT_TYPE 属性更改为MAPI_P1并将 PR_RESPONSIBILITY 属性设置为 TRUE,并将 PrepareSubmit 生成的任何错误返回给客户端。

  2. 在消息的 PR_MESSAGE_FLAGS 属性中设置 MSGFLAG_SUBMIT 标志。

  3. 确保收件人表中有PR_RESPONSIBILITY列,并将其设置为 FALSE,以指示尚未承担传输邮件的责任。

  4. PR_CLIENT_SUBMIT_TIME (PidTagClientSubmitTime) 属性中设置起源日期和时间。

  5. 调用 IMAPISupport::ExpandRecips 以:

    • 展开所有个人通讯组列表和自定义收件人,并将所有已更改的显示名称替换为其原始名称。
    • 删除重复名称。
    • 检查是否有任何必需的预处理,如果需要预处理,请设置 NEEDS_PREPROCESSING 标志和 PR_PREPROCESS (PidTagPreprocess) 属性(为 MAPI 保留的属性)。
    • 如果邮件存储与传输紧密耦合,并且无法处理所有收件人,请设置NEEDS_SPOOLER标志。
  6. 如果设置了NEEDS_PREPROCESSING消息标志,则执行以下任务:

    • pidTagSubmitFlags) 属性的 PR_SUBMIT_FLAGS (SUBMITFLAG_PREPROCESS 位中,将消息放入传出队列中。
    • 通知 MAPI 后台处理程序队列已更改。
    • 将控制权返回到客户端,消息流继续在 MAPI 后台处理程序中。
    • MAPI 后台处理程序执行以下任务:
      • 通过调用 IMsgStore::SetLockState 来锁定消息。
      • 通过按注册顺序调用所有预处理函数来执行所需的预处理。 传输提供程序调用 IMAPISupport::RegisterPreprocessor 来注册预处理函数。
      • 对打开的消息调用 IMessage::SubmitMessage,以向消息存储指示预处理已完成。

如果没有预处理,则客户端进程中将执行以下两个步骤;如果存在预处理,则当 MAPI 后台处理程序调用 SubmitMessage 时,将执行以下两个步骤。

消息存储提供程序

  1. 如果消息存储与传输紧密耦合,并且从 IMAPISupport::ExpandRecips 返回了NEEDS_SPOOLER标志,则执行以下任务:

    • 处理它可以处理的任何收件人。
    • 对于它处理的任何收件人 ,将 PR_RESPONSIBILITY 属性设置为 TRUE。
    • 如果所有收件人都知道此紧密耦合的存储和传输,则执行以下任务:
      • 如果消息已预处理或消息存储提供程序希望 MAPI 后台处理程序完成建议的消息处理,以便可以调用消息传递挂钩,则调用 IMAPISupport::CompleteMsg。 消息流将继续使用 MAPI 后台处理程序,如以下过程所述。
      • 如果未预处理消息或消息存储提供程序不希望 MAPI 后台处理程序完成消息处理,则执行以下任务:
        • 将邮件复制到 PR_SENTMAIL_ENTRYID (PidTagSentMailEntryId) 属性中由条目标识符标识的文件夹(如果已设置)。
        • 如果 PR_DELETE_AFTER_SUBMIT (PidTagDeleteAfterSubmit) 属性已设置为 TRUE,则删除消息。
        • 如果消息已锁定,则解除锁定。
        • 返回到客户端。 消息流已完成。
  2. 如果邮件存储未紧密耦合到传输,并非所有收件人都为邮件存储区所知,或者设置了NEEDS_SPOOLER标志,则执行以下任务:

    • 将消息放入传出队列中,而不在 PR_SUBMIT_FLAGS 属性中设置 SUBMITFLAG_PREPROCESS 位。
    • 通过生成表通知,通知 MAPI 后台处理程序传出队列已更改。
    • 返回到客户端,消息流继续执行 MAPI 后台处理程序执行的一组任务。

当 MAPI 后台处理程序处理消息时,消息存储提供程序会将消息的 PR_SUBMIT_FLAGS 属性设置为SUBMITFLAG_LOCKED。 SUBMITFLAG_LOCKED标志指示 MAPI 后台处理程序已锁定消息以供其独占使用。 PR_SUBMIT_FLAGS的另一个值(SUBMITFLAG_PREPROCESS)是在消息需要由传输提供程序注册的一个或多个预处理器函数进行预处理时设置的。