定期的なアイテムのパターンを読み取って解析する
適用対象: 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 Canonical プロパティを参照してください。 バッファー内のデータの大部分は、固定バイト数のフィールドで構成されます。これは、次々に読み取る必要があります。 一部のフィールドは、他のフィールドに特定の値が含まれている場合にのみ存在し、一部のフィールドのサイズは他のフィールドの値に依存する場合があります。 バッファーを解析してさまざまなフィールドを読み取る場合、多くの簿記が必要です。 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;
}