读取和分析定期模式
适用于:Outlook 2013 | Outlook 2016
MAPI 可用于读取和分析约会的重复模式。
有关如何从本主题中引用的 MFCMAPI 应用程序项目下载、查看和运行代码的信息,请参阅 安装本节中使用的示例。
分析定期 Blob
打开约会项目。 有关打开邮件的信息,请参阅 打开邮件。
检索命名属性 dispidApptRecur (PidLidAppointmentRecur 规范属性) 。 有关检索命名属性的信息,请参阅 MAPI 命名属性。
按照 [MS-OXOCAL] 中的指南读取约会定期模式结构。
MFCMAPI 引用应用程序使用 MFCMapi 项目的InterpretProp2.cpp源文件中的 函数演示最后一步 BinToAppointmentRecurrencePatternStruct
。 函数 BinToAppointmentRecurrencePatternStruct
将指向内存中缓冲区的指针作为参数。 MFCMAPI 应用程序首先将 dispidApptRecur 命名属性映射到属性标记,然后使用 IMAPIProp::GetProps 方法请求属性的值,从而获取此缓冲区。 如果属性太大而无法使用 GetProps 方法进行检索,则 MFCMAPI 会打开一个流接口,以便使用 IMAPIProp::OpenProperty 方法检索该属性。 然后,MFCMAPI 应用程序从流中读取数据以生成缓冲区。
有关缓冲区格式的信息,请参阅 PidLidAppointmentRecur 规范属性。 缓冲区中的大部分数据由固定字节数的字段组成,这些字段必须逐个读取。 仅当其他字段包含特定值时,某些字段才存在,而某些字段的大小可能取决于其他字段的值。 分析缓冲区以读取各种字段涉及大量簿记。 MFCMAPI 使用名为 CBinaryParser
的内部帮助程序类来封装此簿记。 例如,函数 CBinaryParser::GetDWORD
检查缓冲区中是否有足够的字节来读取 DWORD,然后读取值并更新指针。
将缓冲区分析为结构后,MFCMAPI 应用程序使用 AppointmentRecurrencePatternStructToString
函数将该结构转换为要向用户显示的字符串。 这与 Outlook 显示的字符串不同,而是 Outlook 构建其逻辑时所依据的数据的原始视图。
可能会遇到一个缓冲区,该缓冲区包含损坏的数据或比编码重复模式所需的数据更多的数据。 为了帮助识别这些方案,MFCMAPI 应用程序会跟踪已成功分析的数据量以及缓冲区中剩余的数据量。 如果在分析完成后数据保留在缓冲区中,MFCMAPI 会将此“垃圾数据”包含在结构中,以便对其进行检查。
下面是 函数的完整列表 BinToAppointmentRecurrencePatternStruct
。
AppointmentRecurrencePatternStruct* BinToAppointmentRecurrencePatternStruct(ULONG cbBin, LPBYTE lpBin)
{
if (!lpBin) return NULL;
AppointmentRecurrencePatternStruct arpPattern = {0};
CBinaryParser Parser(cbBin,lpBin);
size_t cbBinRead = 0;
arpPattern.RecurrencePattern = BinToRecurrencePatternStruct(cbBin,lpBin,&cbBinRead);
Parser.Advance(cbBinRead);
Parser.GetDWORD(&arpPattern.ReaderVersion2);
Parser.GetDWORD(&arpPattern.WriterVersion2);
Parser.GetDWORD(&arpPattern.StartTimeOffset);
Parser.GetDWORD(&arpPattern.EndTimeOffset);
Parser.GetWORD(&arpPattern.ExceptionCount);
if (arpPattern.ExceptionCount &&
arpPattern.ExceptionCount == arpPattern.RecurrencePattern->ModifiedInstanceCount &&
arpPattern.ExceptionCount < _MaxExceptions)
{
arpPattern.ExceptionInfo = new ExceptionInfoStruct[arpPattern.ExceptionCount];
if (arpPattern.ExceptionInfo)
{
memset(arpPattern.ExceptionInfo,0,sizeof(ExceptionInfoStruct) * arpPattern.ExceptionCount);
WORD i = 0;
for (i = 0 ; i < arpPattern.ExceptionCount ; i++)
{
Parser.GetDWORD(&arpPattern.ExceptionInfo[i].StartDateTime);
Parser.GetDWORD(&arpPattern.ExceptionInfo[i].EndDateTime);
Parser.GetDWORD(&arpPattern.ExceptionInfo[i].OriginalStartDate);
Parser.GetWORD(&arpPattern.ExceptionInfo[i].OverrideFlags);
if (arpPattern.ExceptionInfo[i].OverrideFlags & ARO_SUBJECT)
{
Parser.GetWORD(&arpPattern.ExceptionInfo[i].SubjectLength);
Parser.GetWORD(&arpPattern.ExceptionInfo[i].SubjectLength2);
if (arpPattern.ExceptionInfo[i].SubjectLength2 && arpPattern.ExceptionInfo[i].SubjectLength2 + 1
== arpPattern.ExceptionInfo[i].SubjectLength)
{
Parser.GetStringA(arpPattern.ExceptionInfo[i].SubjectLength2,&arpPattern.ExceptionInfo[i].Subject);
}
}
if (arpPattern.ExceptionInfo[i].OverrideFlags & ARO_MEETINGTYPE)
{
Parser.GetDWORD(&arpPattern.ExceptionInfo[i].MeetingType);
}
if (arpPattern.ExceptionInfo[i].OverrideFlags & ARO_REMINDERDELTA)
{
Parser.GetDWORD(&arpPattern.ExceptionInfo[i].ReminderDelta);
}
if (arpPattern.ExceptionInfo[i].OverrideFlags & ARO_REMINDER)
{
Parser.GetDWORD(&arpPattern.ExceptionInfo[i].ReminderSet);
}
if (arpPattern.ExceptionInfo[i].OverrideFlags & ARO_LOCATION)
{
Parser.GetWORD(&arpPattern.ExceptionInfo[i].LocationLength);
Parser.GetWORD(&arpPattern.ExceptionInfo[i].LocationLength2);
if (arpPattern.ExceptionInfo[i].LocationLength2 && arpPattern.ExceptionInfo[i].LocationLength2
+ 1 == arpPattern.ExceptionInfo[i].LocationLength)
{
Parser.GetStringA(arpPattern.ExceptionInfo[i].LocationLength2,&arpPattern.ExceptionInfo[i].Location);
}
}
if (arpPattern.ExceptionInfo[i].OverrideFlags & ARO_BUSYSTATUS)
{
Parser.GetDWORD(&arpPattern.ExceptionInfo[i].BusyStatus);
}
if (arpPattern.ExceptionInfo[i].OverrideFlags & ARO_ATTACHMENT)
{
Parser.GetDWORD(&arpPattern.ExceptionInfo[i].Attachment);
}
if (arpPattern.ExceptionInfo[i].OverrideFlags & ARO_SUBTYPE)
{
Parser.GetDWORD(&arpPattern.ExceptionInfo[i].SubType);
}
if (arpPattern.ExceptionInfo[i].OverrideFlags & ARO_APPTCOLOR)
{
Parser.GetDWORD(&arpPattern.ExceptionInfo[i].AppointmentColor);
}
}
}
}
Parser.GetDWORD(&arpPattern.ReservedBlock1Size);
if (arpPattern.ReservedBlock1Size && arpPattern.ReservedBlock1Size < _MaxReservedBlock)
{
Parser.GetBYTES(arpPattern.ReservedBlock1Size,&arpPattern.ReservedBlock1);
}
if (arpPattern.ExceptionCount &&
arpPattern.ExceptionCount == arpPattern.RecurrencePattern->ModifiedInstanceCount &&
arpPattern.ExceptionCount < _MaxExceptions &&
arpPattern.ExceptionInfo)
{
arpPattern.ExtendedException = new ExtendedExceptionStruct[arpPattern.ExceptionCount];
if (arpPattern.ExtendedException)
{
memset(arpPattern.ExtendedException,0,sizeof(ExtendedExceptionStruct) * arpPattern.ExceptionCount);
WORD i = 0;
for (i = 0 ; i < arpPattern.ExceptionCount ; i++)
{
if (arpPattern.WriterVersion2 >= 0x0003009)
{
Parser.GetDWORD(&arpPattern.ExtendedException[i].ChangeHighlight.ChangeHighlightSize);
Parser.GetDWORD(&arpPattern.ExtendedException[i].ChangeHighlight.ChangeHighlightValue);
if (arpPattern.ExtendedException[i].ChangeHighlight.ChangeHighlightSize > sizeof(DWORD))
{
Parser.GetBYTES(arpPattern.ExtendedException[i].ChangeHighlight.ChangeHighlightSize
- sizeof(DWORD),&arpPattern.ExtendedException[i].ChangeHighlight.Reserved);
}
}
Parser.GetDWORD(&arpPattern.ExtendedException[i].ReservedBlockEE1Size);
if (arpPattern.ExtendedException[i].ReservedBlockEE1Size &&
arpPattern.ExtendedException[i].ReservedBlockEE1Size < _MaxReservedBlock)
{
Parser.GetBYTES(arpPattern.ExtendedException[i].ReservedBlockEE1Size,&arpPattern.ExtendedException[i].ReservedBlockEE1);
}
if (arpPattern.ExceptionInfo[i].OverrideFlags & ARO_SUBJECT ||
arpPattern.ExceptionInfo[i].OverrideFlags & ARO_LOCATION)
{
Parser.GetDWORD(&arpPattern.ExtendedException[i].StartDateTime);
Parser.GetDWORD(&arpPattern.ExtendedException[i].EndDateTime);
Parser.GetDWORD(&arpPattern.ExtendedException[i].OriginalStartDate);
}
if (arpPattern.ExceptionInfo[i].OverrideFlags & ARO_SUBJECT)
{
Parser.GetWORD(&arpPattern.ExtendedException[i].WideCharSubjectLength);
if (arpPattern.ExtendedException[i].WideCharSubjectLength)
{
Parser.GetStringW(arpPattern.ExtendedException[i].WideCharSubjectLength,&arpPattern.ExtendedException[i].WideCharSubject);
}
}
if (arpPattern.ExceptionInfo[i].OverrideFlags & ARO_LOCATION)
{
Parser.GetWORD(&arpPattern.ExtendedException[i].WideCharLocationLength);
if (arpPattern.ExtendedException[i].WideCharLocationLength)
{
Parser.GetStringW(arpPattern.ExtendedException[i].WideCharLocationLength,&arpPattern.ExtendedException[i].WideCharLocation);
}
}
if (arpPattern.ExceptionInfo[i].OverrideFlags & ARO_SUBJECT ||
arpPattern.ExceptionInfo[i].OverrideFlags & ARO_LOCATION)
{
Parser.GetDWORD(&arpPattern.ExtendedException[i].ReservedBlockEE2Size);
if (arpPattern.ExtendedException[i].ReservedBlockEE2Size && arpPattern.ExtendedException[i].ReservedBlockEE2Size < _MaxReservedBlock)
{
Parser.GetBYTES(arpPattern.ExtendedException[i].ReservedBlockEE2Size,&arpPattern.ExtendedException[i].ReservedBlockEE2);
}
}
}
}
}
Parser.GetDWORD(&arpPattern.ReservedBlock2Size);
if (arpPattern.ReservedBlock2Size && arpPattern.ReservedBlock2Size < _MaxReservedBlock)
{
Parser.GetBYTES(arpPattern.ReservedBlock2Size,&arpPattern.ReservedBlock2);
}
// Junk data remains.
if (Parser.RemainingBytes() > 0)
{
arpPattern.JunkDataSize = Parser.RemainingBytes();
Parser.GetBYTES(arpPattern.JunkDataSize,&arpPattern.JunkData);
}
AppointmentRecurrencePatternStruct* parpPattern = new AppointmentRecurrencePatternStruct;
if (parpPattern)
{
*parpPattern = arpPattern;
}
return parpPattern;
}