查找 POP3 帐户的邮件下载历史记录

本主题介绍邮件客户端如何访问 PidTagAttachDataBinary 属性以获取 POP3 帐户的邮件下载历史记录。

为何获取消息下载历史记录?

适用于 Outlook 的 Pop) 提供程序的邮局协议 (允许用户在其本地设备上检索和下载新电子邮件,然后在邮件服务器上保留或删除这些电子邮件。 当邮件客户端检查要下载的新邮件时,它必须能够识别并仅下载该收件箱的新邮件。 邮件客户端首先使用 UIDL (唯一 ID 列表) 命令执行此操作,该命令获取已传递到该收件箱的每封邮件的映射, (UID) 的唯一标识符。 客户端还会获取已为该客户端上的收件箱下载或删除的邮件的邮件下载历史记录。 然后,使用消息 UID 映射和下载历史记录,客户端可以将历史记录中不存在的消息标识为新消息,因此应下载这些消息。

若要获取收件箱的邮件下载历史记录,请执行以下操作:

  • 按照本主题中的步骤查找 PidTagAttachDataBinary 属性,该属性包含遵循特定格式的二进制大型对象 (BLOB) 中的历史记录。

  • 继续 分析 POP3 帐户的邮件下载历史记录,其中介绍了如何分析此 BLOB 以识别已为该收件箱下载或删除的邮件。

查找消息下载历史记录时需要了解的核心概念

收件箱的邮件下载历史记录存储在二进制 MAPI 属性 PidTagAttachDataBinary 中,位于收件箱中隐藏邮件的附件上。 表 1 显示了有助于了解如何查找消息下载历史记录的概念资源。

表 1. 核心概念

文章标题 说明
MAPI 隐藏文件夹
MAPI 允许邮件客户端将信息存储在隐藏的文件夹和隐藏的邮件中。 隐藏文件夹位于 MAPI 文件夹的关联部分,通常包含对用户不可见和无法操作的信息。 客户端决定在隐藏文件夹中的隐藏邮件中存储的格式和内容。
MAPI 消息
MAPI 将邮件存储在文件夹中,无论是在客户端用户可见的标准 IPM 子树中,还是在子树外部且对用户不可见。 邮件可以将其他数据存储在附件中,附件可以是文件、另一条消息或 OLE 对象的形式。 对于邮件下载历史记录,历史记录存储在附加到另一个隐藏邮件的消息的属性中。
消息属性概述
当客户端在消息中存储信息时,它实际上将信息存储在消息的 属性中。 MAPI 支持许多属性-有些属性始终存在,可由客户端设置,其他属性是可选的,客户端不能期望它们可用或设置为有效值。 邮件下载历史记录存储在隐藏邮件附件的 PidTagAttachDataBinary 属性中。
MAPI 配置文件
在会话登录时,邮件客户端会选择描述要使用的提供程序和服务的配置文件。 配置文件分为包含属性的节。 具体而言, PidTagSearchKey (PR_SEARCH_KEY) 和 PidTagProfileName (PR_PROFILE_NAME 始终存在) 属性。 配置文件的搜索键在所有配置文件中都是唯一的,存储在由 MAPIGUID 中定义的 (MUID_PROFILE_INSTANCE 标识的配置文件部分中。H) 。 使用 IMAPISession::OpenProfileSection 打开节,并使用 IMAPIProp::GetProps 获取属性值。
内容表
消息存储提供程序为其文件夹实现内容表。 对于文件夹关联部分中的隐藏邮件,消息存储提供程序支持关联的内容表,客户端可以使用 IMAPIContainer::GetContentsTable 方法返回指向关联内容表的指针。
关于限制
限制类型
构建限制
示例限制代码
在 MAPI 中,客户端可以使用限制来筛选内容表,以搜索表示具有特定属性设置为特定值的邮件的行。 限制是使用 SRestriction 数据结构定义的,该结构可以包含更专用的限制结构的联合。 IMAPITable::FindRow 方法应用限制并检索表中与限制条件匹配的第一行。
关于为索引注册存储
使用 PidTagStoreProvider (PR_MDB_PROVIDER) 属性验证存储提供程序的类型。 例如,若要验证存储是否为 Exchange 存储, PidTagStoreProvider 属性应返回由公共头文件 edkmdb.h 中定义的 pbExchangeProviderPrimaryUserGuid 常量表示的值。

查找相应的隐藏邮件和附件

现在我们知道收件箱的邮件下载历史记录位于隐藏邮件附件的 PidTagAttachDataBinary 属性中,查找相应隐藏邮件的相应附件的过程涉及以下过程:

  1. 查找相应的隐藏邮件

  2. 查找隐藏邮件的相应附件

  3. 访问邮件附件的 PidTagAttachDataBinary 属性

查找相应的隐藏邮件

  1. 在 MUID_PROFILE_INSTANCE 指定的配置文件部分中,从配置文件中获取 PidTagSearchKey (PR_SEARCH_KEY) 属性。

  2. 通过调用 IMAPIContainer::GetContentsTable 打开“收件箱”文件夹的“关联内容”。

  3. 根据 PidTagConversationKey (PR_CONVERSATION_KEY ) PidTagSearchKey (PR_SEARCH_KEY) 和 PidTagMessageClass (PR_MESSAGE_CLASS) 属性创建限制,以获取包含收件箱关联内容中所有隐藏邮件的表。 下面是从 查找 POP3 UIDL 历史记录中提取的限制示例。

       SRestriction rgRes[3]; 
       SPropValue rgProps[3]; 
       rgRes[0].rt = RES_AND; 
       rgRes[0].res.resAnd.cRes = 2; 
       rgRes[0].res.resAnd.lpRes = &rgRes[1]; 
       rgRes[1].rt = RES_PROPERTY; 
       rgRes[1].res.resProperty.relop = RELOP_EQ; 
       rgRes[1].res.resProperty.ulPropTag = PR_CONVERSATION_KEY; 
       rgRes[1].res.resProperty.lpProp = &rgProps[0]; 
       rgRes[2].rt = RES_PROPERTY; 
       rgRes[2].res.resProperty.relop = RELOP_EQ; 
       rgRes[2].res.resProperty.ulPropTag = PR_MESSAGE_CLASS; 
       rgRes[2].res.resProperty.lpProp = &rgProps[1]; 
       rgProps[0].ulPropTag = PR_CONVERSATION_KEY; 
       rgProps[0].Value.bin = pVals[iSearchKey].Value.bin; // PR_SEARCH_KEY from the profile 
       rgProps[1].ulPropTag = PR_MESSAGE_CLASS; 
       rgProps[1].Value.LPSZ = (LPTSTR)"IPM.MessageManager";
    
  4. 在表中,使用 IMAPITable::FindRow 查找隐藏的消息。

  5. 如果步骤 4 找不到隐藏的消息,请更改限制以使用 PidTagSearchKey (PR_SEARCH_KEY) 而不是 PidTagConversationKey,如下所示:

     rgRes[1].res.resProperty.ulPropTag = rgProps[0].ulPropTag = PR_SEARCH_KEY;
    
  6. 使用 IMAPITable::FindRow 查找隐藏消息。

  7. 如果步骤 6 失败,请更改限制以使用 PidTagSubject (PR_SUBJECT) 等于以下值, (使用 printf 样式替换来保持简洁) 。

     "Outlook Message Manager (%s) (KEY: %s)", PR_PROFILE_NAME, HexFromBin(PR_SEARCH_KEY)
    
  8. 使用 IMAPITable::FindRow 查找隐藏消息。

  9. 如果运行的是 Outlook 2010 或更高版本,请分别对 PidTagProfileName (PR_PROFILE_NAME) PidTagSearchKey (PR_SEARCH_KEY) 使用以下值。

     CHAR g_szGeneralKey[] = "General Key"; 
     const SBinary g_binGeneralKey = {sizeof(g_szGeneralKey), (LPBYTE)g_szGeneralKey};
    

    完成步骤 3 到 8。 如果无法找到消息,请回退到原始步骤 3 到 8。

  10. 打开步骤 4、6 或 8 中找到的隐藏邮件。

查找隐藏邮件的相应附件

由于隐藏邮件可能有多个附件,因此按以下顺序查找相应的附件。

注意

为了简洁起见, printf 此过程再次使用样式替换。

  1. 查找 其 PidTagAttachLongFilename (PR_ATTACH_LONG_FILENAME) 匹配以下字符串的附件,其中 szEmailAddress 是用户的 SMTP 地址,如用户配置文件中指定的。 .

     "BlobPOP%s", szEmailAddress
    
  2. 查找 PidTagAttachFilename (PR_ATTACH_FILENAME) 与“BlobPOP%s”匹配的附件。 szEmailAddress

  3. 查找 PidTagDisplayName (PR_DISPLAY_NAME) 与“BlobPOP%s” szEmailAddress匹配的附件。

  4. 查找其 PidTagAttachFilename (PR_ATTACH_FILENAME) 与“Blob%.8x”匹配的附件,dwAcctUID其中dwAcctUID来自 PROP_ACCT_MINI_UID。 可以使用 IOlkAccount::GetProp 方法访问 PROP_ACCT_MINI_UID 属性。

访问邮件附件的 PidTagAttachDataBinary 属性

找到隐藏邮件的相应邮件附件后,使用 IMAPIProp::GetProps 读取附件的 PidTagAttachDataBinary 属性。

后续步骤

你已从本主题中了解了如何查找 POP3 邮件客户端收件箱的邮件下载历史记录。 请参阅 分析 POP3 帐户的邮件下载历史记录 ,了解如何分析此历史记录,以识别已为收件箱下载或删除的邮件。

另请参阅