Lesen und Analysieren eines Serienmusters
Gilt für: Outlook 2013 | Outlook 2016
MAPI kann verwendet werden, um ein Serienmuster für einen Termin zu lesen und zu analysieren.
Informationen zum Herunterladen, Anzeigen und Ausführen des Codes aus dem MFCMAPI-Anwendungsprojekt, auf das in diesem Thema verwiesen wird, finden Sie unter Installieren der in diesem Abschnitt verwendeten Beispiele.
So analysieren Sie ein Wiederholungsblob
Öffnen Sie ein Terminelement. Informationen zum Öffnen einer Nachricht finden Sie unter Öffnen einer Nachricht.
Rufen Sie die benannte Eigenschaft dispidApptRecur (Kanonische PidLidAppointmentRecur-Eigenschaft) ab. Informationen zum Abrufen benannter Eigenschaften finden Sie unter Benannte MAPI-Eigenschaften.
Befolgen Sie die Anleitung in [MS-OXOCAL], um die Musterstruktur der Terminserie zu lesen.
Die MFCMAPI-Referenzanwendung veranschaulicht den letzten Schritt mit der BinToAppointmentRecurrencePatternStruct
Funktion in der InterpretProp2.cpp Quelldatei des MFCMapi-Projekts. Die BinToAppointmentRecurrencePatternStruct
Funktion verwendet einen Zeiger auf einen Puffer im Arbeitsspeicher als Parameter. Die MFCMAPI-Anwendung ruft diesen Puffer ab, indem sie zuerst die benannte dispidApptRecur-Eigenschaft einem Eigenschaftstag zuordnen und dann den Wert der Eigenschaft mithilfe der IMAPIProp::GetProps-Methode anfordert . Wenn die Eigenschaft zu groß ist, um sie mit der GetProps-Methode abzurufen, öffnet MFCMAPI eine Streamschnittstelle, um die Eigenschaft mithilfe der IMAPIProp::OpenProperty-Methode abzurufen. Die MFCMAPI-Anwendung liest dann die Daten aus dem Stream, um den Puffer zu erstellen.
Informationen zum Format des Puffers finden Sie unter der kanonischen PidLidAppointmentRecur-Eigenschaft. Der Großteil der Daten im Puffer besteht aus Feldern mit einer festen Anzahl von Bytes, die nacheinander gelesen werden müssen. Einige Felder sind nur vorhanden, wenn andere Felder bestimmte Werte enthalten, und die Größe einiger Felder kann vom Wert anderer Felder abhängen. Das Analysieren des Puffers zum Lesen der verschiedenen Felder erfordert viel Buchhaltung. MFCMAPI verwendet eine interne Hilfsklasse namens CBinaryParser
, um diese Buchhaltung zu kapseln. Beispielsweise überprüft die CBinaryParser::GetDWORD
Funktion, ob genügend Bytes im Puffer verbleiben, um ein DWORD zu lesen, und liest dann den Wert und aktualisiert die Zeiger.
Nachdem der Puffer in eine -Struktur analysiert wurde, verwendet die MFCMAPI-Anwendung die AppointmentRecurrencePatternStructToString
-Funktion, um die Struktur in eine Zeichenfolge zu konvertieren, die dem Benutzer angezeigt wird. Dies ist nicht die gleiche Zeichenfolge, die Outlook anzeigen würde, sondern eine unformatierte Ansicht der Daten, auf denen Outlook seine Logik erstellt.
Es ist möglich, auf einen Puffer zu stoßen, der entweder beschädigte Daten oder mehr Daten enthält, als zum Codieren eines Serienmusters erforderlich sind. Um diese Szenarien zu identifizieren, verfolgt die MFCMAPI-Anwendung, wie viele Daten erfolgreich analysiert wurden und wie viel im Puffer verbleibt. Wenn Daten nach Abschluss der Analyse im Puffer verbleiben, schließt MFCMAPI diese "Junk-Daten" in die Struktur ein, damit sie untersucht werden können.
Im Folgenden finden Sie die vollständige Auflistung der BinToAppointmentRecurrencePatternStruct
Funktion.
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;
}