Zum Inhalt springen
Deutsch

Outlook rules

Dieser Inhalt ist noch nicht in deiner Sprache verfügbar.

Specification for the Outlook (2016–2021) RWZ rule stream and file format. Available information for older versions is sporadicly sprinkled in.

Rules are used to do custom processing on messages. Both incoming and outgoing messages can be modified or otherwise acted upon. Common tasks are, for example: sorting incoming messages into different folders, marking incoming messages with certain colors, issuing automatic responses while out of office, or automatic forwarding while out of office.

Such rules are stored by Outlook all over the place (unfortunately).

Deferred actions are called client-side rules in Exchange/Outlook circles, but this name is misleading since only very few of the conditions and actions one could possibly use in rules actually require a running client in the first place.

Rules can also be defined for public folders. The dialog for this in Outlook however reeks of the 16-bit era and is much more limited than the one for private stores; that dialog only supports the features of server-side rules, and server-side rules are the only storage medium. There are no FAI messages to hold copies of the configuration.

In the Inbox's Associated Contents folder, there is one message containing distinctive properties:

PR_SUBJECT
Static value OutlookRulesOrganizer.

PR_MESSAGE_CLASS
Static value IPM.RuleOrganizer.

PR_RW_RULES_STREAM
See section Rules Stream

PR_RW_RULES_STREAM contains most of the ruleset, including receiving and sending rules, but not OOF rules. See section Rules stream.

In the Inbox's Associated Contents folder, there are a number of messages that represent each rule from PR_RW_RULES_STREAM. These RuleV2 messages have these characteristic properties:

PR_MESSAGE_CLASS
Static value IPM.Rule.Version2.Message.

PR_RULE_MSG_LEVEL
Equivalent to PR_RULE_LEVEL from the SSRT.

PR_RULE_MSG_NAME
Equivalent to PR_RULE_NAME.

PR_RULE_MSG_PROVIDER
Static value Organizer2.

PR_RULE_MSG_PROVIDER_DATA
Equivalent to PR_RULE_PROVIDER_DATA.

For the TDX OOF provider (more on that later), the property is unset.

For the Organizer2 provider, a 16-byte packed value:

struct {
uint32_t magic[2] = {1, 1};
double timestamp; /* PT_APPTIME */
};

PR_RULE_MSG_SEQUENCE
Equivalent to PR_RULE_SEQUENCE. Outlook starts with sequence number 10.

PR_RULE_MSG_STATE
Equivalent to PR_RULE_STATE.

PR_RULE_MSG_USER_FLAGS
Equivalent to PR_RULE_USER_FLAGS.

PR_EXTENDED_RULE_MSG_CONDITION
Binary data, pretty much equivalent to the data presented through PR_RULE_CONDITION without significant differences. Some 16-bit fields are now 32-bit, and, according to MSDN, there is some additional room for expressing named properties; Unicode strings are forced.

PR_EXTENDED_RULE_MSG_ACTION
(no notes)

A notation similar to C++ struct declarations with initializers is used in this document. Numeric values are presented as an abstract number and their representation in the rule stream is in little-endian format. That is, the notation uint16_t x = 0x8001; concurs with a byte sequence of 01 80.

In the OL 1998/2000 formats, strings are 8-bit, so TCHAR s[len] means exactly len octets. In the OL 2002+ formats, strings are UTF-16, so TCHAR s[len] means len times 2 octets. Unless otherwise noted, there is no NUL terminator included in any string.

If an 8-bit length field has value 0xFF, there is generally a 16-bit length field following, which overrides it. It is not known if the 3B encoding for values below 255 is to be rejected in similar spirit how UTF-8 mandates exactly one encoding only.

Logical value 1B encoding 3B encoding
0 00 ff 00 00
253 fd ff fd 00
254 fe ff fe 00
255 ff ff 00
256 ff 00 01
257 ff 01 01
65534 ff fe ff
65535 — ``ff ff ff``

In the XR element sections further below, this is always spelled out, in three ways:

  1. The absence of 3B encoding has been verified:

    uint8_t len;
  2. The Outlook UI prevents the user from entering a long enough value, or the user cannot otherwise influence its length to observe behavior with 255 chars or more:

    uint8_t len;
    if (len == 0xff) /* conjecture */
    uint16_t len;
  3. The presence of 3B encoding has been verified:

    uint8_t len;
    if (len == 0xff)
    uint16_t len;

PT_APPTIME timestamps are a 64-bit IEEE floating point number, in which the integral part represents the number of days since about December 30, 1899, and the fractional part represents the fraction of a day since midnight. There is no timezone information attached.

This unusual base date stems from three defining characteristics:

  • the first usable day is 1900-01-01
  • the starting index is 1
  • index 60 maps to the (non-existing) 1900-02-29, and 1900-03-01 is then index 61.

A condition shown in the UI as "before 2018-01-01" is stored as less-than(0x40e5394e...). "after 2017-12-31" is stored as greater-than(0x40e5394d...), rather than a more straightforward greater-or-equals(0x40e5394e...), so one will see different patterns for effectively the same point in time.

The OL2019 UI erroneously applies the current time when constructing the timestamp value from the date picker. Creating the same conditions "before 2019-01-01" twice, once at 11:58 and once at 12:00, will actually yield two different bit patterns (0x40e5395227d2d728 and 0x40e5393222222222) and different semantics, but the user is never told.

Detailed derivation:

Date Observed value 1 Observed value 2
2019-01-01 0xd27d27d2 0x40e53950
2018-12-31 0xd27d27d2 0x40e53930
1989-09-18 ignored 0x40e00020
1989-09-17 ignored 0x40e00000
1989-09-16 ignored 0x40dfffd0
1989-09-15 ignored 0x40dfff90
1989-09-14 ignored 0x40dfff50

OV1 has a prominent bit pattern, suggestive of a canary value for indicating freed memory — however, 12 bits is an usual repeat cadence for such magic markers. OV2 steps in units of 32 per day. The pattern breaks between 1989-09-16 and 1989-06-15. The DST switch however is one week away. The step for earlier dates is 64 units per day. An increase of precision for smaller values is strongly suggestive of a floating-point value (as the integral part requires fewer bits, more are available for the fractional part). By trying around, one finds that OV1 does actually belong to the float.

OL applies the hour and minute to the timestamp, but not seconds or subseconds, so the fractional part is always a multiple of 1/1440. The curious bit patterns in OV1 are a result of 9 being a factor of 1440.

RW_Magic;
uint16_t numrules;
repeat numrules {
XR_Magic;
};
uint32_t tdlen;
TCHAR template_dir[tdlen];
uint32_t magic = 0;
double timestamp;
uint32_t magic = 0;

template_dir
The most recently used location from which a template file was used. (This is used for UI display purposes only.)

Rule order is defined by their logical position to one another in XR_Begin.

if (format >= ol2016)
uint8_t magic[8] = {0, 0, 0x14, 0, 0, 0, 0x14, 0x06};
else if (format == ol2002)
uint8_t magic[8] = {0x40, 0x42, 0x0f, 0, 0, 0, 0x14, 0x06};
else if (format == ol2000)
uint8_t magic[4] = {0xbd, 0x5e, 0x0e, 0};
else if (format == ol1998)
uint8_t magic[4] = {0x3c, 0xd0, 0x0e, 0};
uint32_t unknown[6] = {0, 0, 0, 0, 0, 0};
uint32_t unknown[2] = {1, 1};
if (format >= ol2002)
uint32_t unknown = 0;
uint8_t magic[3];

magic
The bit pattern suggests this could be a flags field.

  • 00 00 14: OL2016/2019/2021 XR_Rule
  • 40 42 0f: OL2002 XR_Rule
  • 80 4f 12: XR_Rule (alternative 2)
  • e0 c8 10: XR_Rule (alternative 3)
  • 6e 54 3d: AR_DeferAction
XR_Header;
repeat zero-or-more {
<any XR_Condition or XR_Action>;
if (there are more conds/actions)
XR_Separator;
};

The size of a XR element can be variadic and generally there are no length indiciators. The byte stream is therefore best parsed field-by-field rather than struct-at-a-time.

The Unknown 0x190 is practically present at all times as the first element.

The Condition 0x64 is practically present at all times as the second element (i.e. first condition), even though it does not serve any observable purpose and is not displayed as anything in the UI.

The order of elements is generally: 0x190, then all conditions, then all actions, and only then exception conditions.

if (format >= ol2002)
XR_Magic;
uint8_t locator;
uint8_t rname_len;
if (rname_len == 0xff)
uint16_t rname_len;
TCHAR rule_name[rname_len];
uint32_t rule_is_active;
if (format >= ol2002)
uint32_t unknown = 0;
alternative {
uint32_t ptact_recv_rule_activated[] = {0, 0, 1};
uint32_t ptact_recv_rule_activated2[] = {0, 0, 2};
uint32_t strm_recv_rule_activated[] = {1, 0, 1};
uint32_t strm_recv_rule_activated2[] = {1, 0, 2};
uint32_t strm_recv_rule_activated3[] = {1, 0, 3};
uint32_t strm_recv_rule_deactivated[] = {0, 0, 0};
uint32_t strm_send_rule_activated[] = {0, 0, 0};
uint32_t strm_send_rule_deactivated[] = {0, 0, 0};
} magic;
if (format >= ol2002)
uint32_t bytecount;
uint16_t rule_elements;
uint16_t separator;
if (separator == 0xffff) {
uint16_t magic = 0;
uint16_t rcls_len;
char rule_class[rcls_len];
} else if (separator == 0x8001) {
/* ok */
} else {
REJECT-PARSE;
}

locator
A magic value:

  • 00: via PR_RULE_ACTIONS
  • 06: via PR_RW_RULES_STREAM

bytecount
The bytecount of literally everything following the bytecount member; this includes not only the remaining fields of the XR Header, but also all the other XR separators and elements.

rule_elements
The number of subsequent XR elements. XR separators do not count into this.

rule_class
Static value CRuleElement.

The OL2019 UI arbitrarily restricts rule names to 256 characters by ignoring excess keypresses.

uint16_t magic = 0x8001;

This common structure appears for reference in other XR elements.

uint32_t magic = 0;
uint32_t numprops;
uint32_t bytes_in_propblock;
/* propblock begins here */
repeat numprops {
uint32_t proptag;
switch (PROP_TYPE(proptag)) {
case PT_UNICODE:
/* Conjecture: probably also applies for PT_STRING8 */
uint32_t magic = 0;
uint32_t offset_from_propblock;
uint32_t magic = 0;
break;
case PT_BINARY:
uint32_t magic = 0;
uint32_t proplen;
uint32_t offset_from_propblock;
break;
case PT_LONG:
case PT_ERROR:
case PT_BOOLEAN:
uint32_t magic = 0;
uint32_t propvalue;
uint32_t magic = 0;
break;
}
} propindex;
char data[bytes_in_propblock - 16 * numprops];
/* propblock ends here */

data
This is a concatenation of the values for properties of type PT_BINARY and PT_UNICODE, in the same order as the index. Within XR_PropValArray, PT_UNICODE strings are followed by a U+0000 codepoint, and this is the only way to determine their length.

Emission of PT_STRING8 was not observed with OL2019.

UI label:

Not visible in the UI at all.

Layout:

uint32_t act_kind = 0x64;
uint32_t magic[] = {1, 0, 1};

UI label:

  • EN: where my name is in the To box
  • DE: die meinen Namen im Feld "An" enthält

UI behavior:

Only selectable for receive rules.

Layout:

uint32_t act_kind = 0xc8;
uint32_t magic = 0;

SRestriction:

{RES_PROPERTY, RELOP_EQ, PR_MESSAGE_TO_ME, true}

UI label:

  • EN: sent only to me
  • DE: die nur an mich gesendet wurde

UI behavior:

Only selectable for receive rules.

Layout:

uint32_t act_kind = 0xc9;
uint32_t magic = 0;

SRestriction:

{RES_AND, {
{RES_PROPERTY, RELOP_EQ, PR_MESSAGE_TO_ME, true},
{RES_NOT, {RES_CONTENT, FL_SUBSTRING, PR_DISPLAY_TO, ";"}},
{RES_PROPERTY, RELOP_EQ, PR_DISPLAY_CC, ""},
}}

UI label:

  • EN: where my name is not in the To box
  • DE: die meinen Namen im Feld "An" nicht enthält

UI behavior:

Only selectable for receive rules.

Layout:

uint32_t act_kind = 0xca;
uint32_t magic = 0;

SRestriction:

{RES_PROPERTY, RELOP_EQ, PR_MESSAGE_TO_ME, false}

UI label:

  • EN: from <people or public group>
  • DE: die von <einer Person/öffentlichen Gruppe> kommt

UI behavior:

Only selectable for receive rules.

Layout:

uint32_t act_kind = 0xcb;
uint32_t magic[] = {1, 0};
uint32_t numrcpt; /* numsenders */
repeat numrcpt {
XR_PropValArray;
};
uint32_t magic[] = {1, 0};

SRestriction:

{RES_COMMENT,
lpProp={
{PROP_TAG(PT_LONG, 0x6000), 1},
{PROP_TAG(PT_BINARY, 0x0001), <PR_ENTRYID from an ABK or OneOff>},
{PROP_TAG(PT_TSTRING, 0x0001), <Display name of recipient>},
{PR_DISPLAY_TYPE, DT_MAILUSER}},
lpRes={
{RES_PROPERTY, RELOP_EQ, PR_SENDER_SEARCH_KEY,
"EX:/O=TOPORGUM/..."}},
}

Specifying multiple senders will add a level of RES_OR.

The propvalarray for an EX entity typically includes 11 props:

proptag v1 v2 v3
0x0c150003 (PR_RECIPIENT_TYPE) 0 1 (MAPI_TO) 0
0x3001001f (PR_DISPLAY_NAME) 0 0xb0 0
0x0fff0102 (PR_ENTRYID) 0 0x7d 0xd0
0x3002001f (PR_ADDRTYPE) 0 0x14d 0
0x300b0102 (PR_SEARCH_KEY) 0 0x64 0x153
0x39fe001f (PR_SMTP_ADDRESS) 0 0x1b7 0
0x0ffe0003 (PR_OBJECT_TYPE) 0 0x6 (MAPI_MAILUSER) 0
0x39000003 (PR_DISPLAY_TYPE) 0 0 (DT_MAILUSER) 0
0x39050003 (PR_DISPLAY_TYPE_EX) 0 0x40000000 (DTE_FLAG_ACL_CAPABLE) 0
0x3003001f (PR_EMAIL_ADDRESS) 0 0x1d9 0
0x3d010102 (PR_AB_PROVIDERS) 0 0x10 0x2b9

PR_RECIPIENT_TYPE
MAPI_TO apparently serves double purpose here.

PR_ENTRYID
00000000dca740c8c042101ab4b908002b2fe18201000000000000002f6f3d636f6d70616e792f636e3d2e2e2e00

PR_ADDRTYPE
EX

PR_SEARCH_KEY
EX:/O=COMPANY/...

PR_SMTP_ADDRESS
[email protected]

PR_EMAIL_ADDRESS
/o=company/...

PR_AB_PROVIDERS
{02c29c57-985c-417b-e084-c5f0b5f7be02}

Note that both senders and recipients share the same representation (here, as MAPI Recipients); this is just like how addr-spec is used in RFC5322-style e-mails.

The propvalarray for an SMTP entity typically includes 12 props:

proptag v1 v2 v3
0x0c150003 (PR_RECIPIENT_TYPE) 0 1 (MAPI_TO) 0
0x3001001f (PR_DISPLAY_NAME) 0 0xc0 0
0x0fff0102 (PR_ENTRYID) 0 0x62 0xe0
0x3002001f (PR_ADDRTYPE) 0 0x142 0
0x300b0102 (PR_SEARCH_KEY) 0 0x15 0x14c
0x39fe000a (PR_SMTP_ADDRESS:PT_ERROR) 0 0x8004010f (MAPI_E_NOT_FOUND) 0
0x3a710003 (PR_SEND_INTERNET_ENCODING) 0 0 0
0x3a40000b (PR_SEND_RICH_INFO) 0 0 0
0x39000003 (PR_DISPLAY_TYPE) 0 0 (DT_MAILUSER) 0
0x0ff90102 (PR_RECORD_KEY) 0 0x62 0x161
0x0ffe0003 (PR_OBJECT_TYPE) 0 0x6 0
0x3003001f (PR_EMAIL_ADDRESS) 0 0x1c3 0

PR_RECIPIENT_TYPE
MAPI_TO

PR_ENTRYID
Happens to be the same value as PR_RECORD_KEY.

PR_ADDRTYPE
SMTP

PR_SEARCH_KEY
SMTP:[email protected]

PR_RECORD_KEY
00000000812b1fa4bea310199d6e00dd010f5402000001906100620063006400650066006700400069006a006b006c002e0064006500000053004d005400500000006100620063006400650066006700400069006a006b006c002e00640065000000

PR_EMAIL_ADDRESS
[email protected]

UI label:

  • EN: sent to <people or public group>
  • DE: die an <einer Person/öffentlichen Gruppe> gesendet wurde [sic]

The layout is the same as From (0xcb), but with act_kind=0xcc.

SRestriction:

{RES_COMMENT,
lpProp={
{PROP_TAG(PT_LONG, 0x6000), 1},
{PROP_TAG(PT_BINARY, 0x0001), <PR_ENTRYID from an ABK or OneOff>},
{PROP_TAG(PT_TSTRING, 0x0001), <Display name of recipient>},
{PR_DISPLAY_TYPE, DT_MAILUSER}},
lpRes={
{RES_PROPERTY, RELOP_EQ, PR_SEARCH_KEY,
"EX:/O=TOPORGUM/..."}},
}

Specifying multiple recipients will add a level of RES_OR.

UI label:

  • EN: with <specific words> in the subject
  • DE: mit <bestimmten Wörtern> im Betreff

Layout:

uint32_t act_kind = 0xcd;
uint32_t matches;
repeat matches {
uint32_t possibly_flags = 0;
uint8_t mlen;
if (mlen == 0xff)
uint16_t mlen;
TCHAR substring[mlen];
} m;

SRestriction:

{RES_CONTENT, FL_IGNORECASE | FL_SUBSTRING, PR_SUBJECT, "text"}

Specifying multiple strings will add a level of RES_OR.

UI behavior:

The UI offers no way to set any flags, and based upon the UI text and observed runtime behavior, FL_IGNORECASE|FL_SUBSTRING is always in effect with flags==0.

The OL2019 UI arbitrarily restricts substrings to 255 characters by ignoring excess keypresses.

UI label:

  • EN:"with <specific words> in the body"
  • DE:"mit <bestimmten Wörtern> im Text"

The layout is the same as Subject (0xcd), but with act_kind=0xce.

SRestriction:

{RES_CONTENT, FL_IGNORECASE | FL_SUBSTRING, PR_BODY, "text"}

Specifying multiple strings will add a level of RES_OR.

Condition 207 (0xcf): Subject or body words

Section titled “Condition 207 (0xcf): Subject or body words”

UI label:

  • EN: with <specific words> in the subject or body
  • DE: mit <bestimmten Wörtern> im Betreff oder Text

The layout is the same as Subject (0xcd), but with act_kind=0xcf.

SRestriction:

{RES_OR, {
{RES_CONTENT, FL_IGNORECASE | FL_SUBSTRING, PR_SUBJECT, "t"},
{RES_CONTENT, FL_IGNORECASE | FL_SUBSTRING, PR_BODY, "t"},
}}

Specifying multiple strings will not add a level of RES_OR; the existing RES_OR will be filled.

UI label:

  • EN: flagged for <action>
  • DE: die mit <einer Aktion> gekennzeichnet ist

UI behavior:

Only selectable for receive rules.

Layout:

uint32_t act_kind = 0xd0;
uint32_t magic[] = {1, 0, 0};
uint8_t nlen;
if (nlen == 0xff)
uint16_t nlen;
TCHAR action[nlen];
uint32_t magic = 1;

SRestriction:

{RES_AND, {
{RES_PROPERTY, RELOP_EQ, PR_FLAG_STATUS, followupFlagged},
{RES_PROPERTY, RELOP_EQ,
PROP_TAG(PT_TSTRING, 0x802A), "action"},
}}

UI label:

  • EN: marked as <importance>
  • DE: die mit <Priorität> markiert ist

Layout:

uint32_t act_kind = 0xd2;
uint32_t magic[] = {1, 0};
enum : uint32_t {
IMPORTANCE_LOW = 0
IMPORTANCE_MEDIUM = 1,
IMPORTANCE_HIGH = 2,
} level;

SRestriction:

{RES_PROPERTY, RELOP_EQ, PR_IMPORTANCE, level}

UI label:

  • EN: marked as <sensitivity>
  • DE: die mit <Vertraulichkeit> markiert ist

Layout:

uint32_t act_kind = 0xd3;
uint32_t magic[] = {1, 0};
enum : uint32_t {
SENSITIVITY_NORMAL = 0
SENSITIVITY_PERSONAL = 1,
SENSITIVITY_PRIVATE = 2,
SENSITIVITY_COMPANY_CONFIDENTIAL = 3,
} level;

SRestriction:

{RES_PROPERTY, RELOP_EQ, PR_SENSITIVITY, level}

UI label:

  • EN: assigned to <category> category
  • DE: die Kategorie <Kategorie zugeordnet ist>

Layout:

uint32_t act_kind = 0xd7;
uint32_t magic[] = {1, 0};
uint8_t cname_len;
if (cname_len == 0xff)
uint16_t cname_len;
TCHAR categories[cname_len];

SRestriction:

(Not mapped)

categories
A semicolon-separated string of categories. As a consequence, category names are not allowed to contain semicolons, and the OL2019 UI inhibits the keypress.

All specified categories must be present on the message for the match to occur. (Labeling: DE:Nach Erhalt einer Nachricht ... die Kategorie C1 und C2 zugeordnet ist...)

UI label:

  • EN: which is an automatic reply
  • DE: die eine automatische Antwort ist

UI behavior:

Only selectable for receive rules.

Layout:

uint32_t act_kind = 0xdc;
uint32_t magic = 0;

SRestriction:

{RES_PROPERTY, RELOP_EQ, PR_MESSAGE_CLASS,
"IPM.Note.Rules.OofTemplate.Microsoft"}

UI label:

  • EN: which has an attachment
  • DE: mit einer Anlage

Layout:

uint32_t act_kind = 0xde;
uint32_t magic = 0;

SRestriction:

{RES_BITMASK, BMR_NEZ, PR_MESSAGE_FLAGS, MSGFLAG_HASATTACH}

UI label:

  • EN: with <selected properties> of documents or forms
  • DE: mit Dokument-/Formular-<Eigenschaften>

Layout:

uint32_t act_kind = 0xdf;
uint32_t magic[] = {1, 0};
uint8_t flen;
if (flen == 0xff)
uint16_t flen;
TCHAR forms[flen];
uint16_t numprops;
repeat numprops {
uint8_t flen;
if (flen == 0xff) /* conjecture */
uint16_t flen;
TCHAR fieldname[flen];
uint32_t proptag;
enum : uint32_t {
CONTAINS = 0,
IS_EQUAL = 1,
NOT_CONTAINS = 2,
} string_match_type;
uint8_t svlen;
if (svlen == 0xff) /* conjecture */
uint16_t svlen;
TCHAR v_string[svlen];
enum : uint32_t {
EQ = 0,
NE = 1,
LE = 2, /* called "at most" */
GE = 3, /* called "at least" */
GT = 4,
LT = 5,
} long_match_type;
uint32_t magic = 0;
uint32_t v_long;
uint32_t v_boolean; /* seemingly inverted */
uint32_t magic = 1;
enum : uint32_t {
BEFORE = 0,
AFTER = 1,
} time_match_type;
uint32_t magic = 0;
double v_apptime;
uint32_t magic = 0;
};
uint32_t classcount;
repeat classcount {
uint8_t clen;
if (clen == 0xff) /* conjecture */
uint16_t clen;
char msgclass[clen];
};

SRestriction:

(Not mapped)

forms
A semicolon-space-separated list of forms to load (e.g. Aufgabe annehmen; InfoPath-Formular).

flen
(When constructing custom forms, Outlook arbitrarily restricts field names to 32 characters by ignoring excess keypresses. A clen >= 255 was not observable.)

fieldname
Descriptive string for the property/field.

proptag

  • 0x68010003: IPM.Outlook.Recall a.k.a. DE:Nachrichtenrückruf: Kennzeichnungen
  • 0x6803000b: IPM.Outlook.Recall a.k.a. DE:Nachrichtenrückruf: Sendebericht
  • 0x8zzzzzzz: various named properties

Even though some properties have PROP_TYPE()==PT_SYSTIME, the value is converted and stored as a floating point timestamp in the stream.

string_match_type
For PT_UNICODE, contains the choice the user made. Otherwise, 0.

svlen
For PT_UNICODE, contains the length of the substring following. Otherwise, 0.

v_string
For PT_UNICODE, contains the choice the user made.

long_match_type
For PT_LONG, contains the choice the user made. Otherwise, 0.

v_long
For PT_LONG, contains the choice the user made. Otherwise, 0.

v_boolean
For PT_BOOLEAN, contains the inverse of the choice the user made (Yes=0, No=1). Otherwise, 0.

v_apptime
For PT_SYSTIME/PT_APPTIME, contains the date/time choice the user made. Otherwise, OL fills this with the creation date of the subcondition.

UI label:

  • EN: with a size <in a specific range>
  • DE: mit <einer bestimmten Größe> (KB)

Layout:

uint32_t act_kind = 0xe0;
uint32_t magic[] = {1, 0};
uint32_t min_size_kb;
uint32_t max_size_kb;

SRestriction:

{RES_AND, {
{RES_PROPERTY, RELOP_GT, PR_MESSAGE_SIZE, xx},
{RES_PROPERTY, RELOP_LE, PR_MESSAGE_SIZE, yy},
}}

UI label:

  • EN: received <in a specific date span>
  • DE: die <in einem bestimmten Zeitraum> erhalten wurde

UI behavior:

Only selectable for receive rules.

Layout:

uint32_t act_kind = 0xe1;
uint32_t magic[] = {1, 0};
uint32_t test_after;
uint32_t magic = 0;
double ts_after;
uint32_t test_before;
uint32_t magic = 0;
double ts_before;

SRestriction:

{RES_PROPERTY, RELOP_GT, PR_MESSAGE_DELIVERY_TIME, xx}

or

{RES_PROPERTY, RELOP_LE, PR_MESSAGE_DELIVERY_TIME, yy}

both combined via RES_AND.

test_after
Boolean indicating whether or not to run a comparison NOW > ts_after.

test_before
Boolean indicating whether or not to run a comparison NOW < ts_before.

ts_after
Timestamp for the "is-after" check. See the "Timestamp" section for details.

ts_before
Timestamp for the "is-before" check. Curiously, this field, together with the ts_before field from the Except date condition (Element 0x20d), are the only two timestamps which have its fractional part correctly set to zero by the OL2019 Date Picker.

UI label:

  • EN: where my name is in the Cc box
  • DE: die meinen Namen im Feld "Cc" enthält

UI behavior:

Only selectable for receive rules.

Layout:

uint32_t act_kind = 0xe2;
uint32_t magic = 0;

SRestriction:

{RES_AND, {
{RES_PROPERTY, RELOP_EQ, PR_MESSAGE_CC_ME, true},
{RES_PROPERTY, RELOP_EQ, PR_MESSAGE_RECIP_ME, true},
{RES_PROPERTY, RELOP_EQ, PR_MESSAGE_TO_ME, false},
}}

UI label:

  • EN: where my name is in the To or Cc box
  • DE: die meinen Namen im Feld "An" oder "Cc" enthält

UI behavior:

Only selectable for receive rules.

Layout:

uint32_t act_kind = 0xe3;
uint32_t magic = 0;

SRestriction:

{RES_PROPERTY, RELOP_EQ, PR_MESSAGE_RECIP_ME, true}

Condition 228 (0xe4): Form / message class

Section titled “Condition 228 (0xe4): Form / message class”

UI label:

  • EN: uses the <form name> form
  • DE: die das Formular <Formularname> verwendet

Layout:

uint32_t act_kind = 0xe4;
uint32_t numforms;
uint32_t magic = 0;
repeat numforms {
uint8_t nlen;
if (nlen == 0xff)
uint16_t nlen;
TCHAR name[nlen];
uint8_t clen;
if (clen == 0xff) /* conjecture */
uint16_t clen;
char msgclass[clen];
};

SRestriction:

{RES_OR, {
{RES_PROPERTY, RELOP_EQ, PR_MESSAGE_CLASS, "IPM.Note.MyName"},
}}

The RES_OR is always present, even if just a single class is used.

The OL2019 UI, when saving forms, arbitrarily restricts form names to 128 characters by ignoring excess keypresses. A nlen >= 255 was therefore not observable. Through the Options menu, one can subsequently edit the display name (but not the message class) and set longer names.

If the message has at least one of the forms (same as message class?) presented in this condition element, then the condition will already match.

name
The display name of the form.

msgclass
The form's message class. See Message Classes for a list of observed values.

UI label:

  • EN: with <specific words> in the recipient's address
  • DE: mit <bestimmten Wörtern> in der Empfängeradresse

The layout is the same as Subject words (0xcd), but with act_kind=0xe5.

SRestriction:

{RES_CONTENT, FL_SUBSTRING, PR_SEARCH_KEY, "SMTP:[email protected]"}

UI label:

  • EN: with <specific words> in the sender's address
  • DE: mit <bestimmten Wörtern> in der Absenderadresse

UI behavior:

Only selectable for receive rules.

The layout is the same as Subject words (0xcd), but with act_kind=0xe6.

SRestriction:

{RES_CONTENT, FL_SUBSTRING, PR_SENDER_SEARCH_KEY, "SMTP:[email protected]"}

UI label:

  • EN: with <specific words> in the message header
  • DE: mit <bestimmten Wörtern> im Nachrichtenkopf

UI behavior:

Only selectable for receive rules.

The layout is the same as Subject (0xcd), but with act_kind=0xe8.

SRestriction:

{RES_CONTENT, FL_IGNORECASE | FL_SUBSTRING,
PR_TRANSPORT_MESSAGE_HEADERS, "text"}

UI label:

  • EN: though the <specified> account
  • DE: über Konto <Kontoname>

UI behavior:

When this element is selected, Outlook also selects "Condition: Machine", and one cannot deselect Machine.

Layout:

uint32_t act_kind = 0xee;
uint32_t magic[] = {1, 0};
uint8_t alen;
if (alen == 0xff) /* conjecture */
uint16_t alen;
TCHAR account_name[alen];
uint8_t abc_len;
if (abc_len == 0xff) /* conjecture */
uint16_t abc_len;
char abc[abc_len];

SRestriction:

(Not mapped)

(The MAPI control panel limits profile names to 63 characters, by the way.)

account_name
An account within the current MAPI profile, specifically the account's display name (which is usually an e-mail address and which the MAPI/OL config dialogs refuse to make editable).

abc
Content unclear. It was observed to be a 10-digit number represented as an ASCII string.

UI label:

  • EN: on this computer only
  • DE: nur auf diesem Computer

Layout:

uint32_t act_kind = 0xef;
uint32_t magic[] = {1, 0};
unsigned char some_guid[16];

SRestriction:

(Not mapped)

UI label:

  • EN: sender is in <specified> Address Book
  • DE: deren Versender im Adressbuch <Adressbuchname> vorkommt

UI behavior:

Only selectable for receive rules.

Layout:

uint32_t act_kind = 0xf0;
uint32_t magic[] = {1, 0};
uint32_t eidlen;
char eid[eidlen];
uint8_t nlen;
if (nlen == 0xff) /* conjecture */
uint16_t nlen;
TCHAR name[nlen];

SRestriction:

(Not mapped)

eid
For example,

00000000 00 00 00 00 87 12 f5 ef 5b 95 8f 43 94 a0 89 8c ........[..C....
00000010 07 4d 16 c4 01 00 00 00 00 01 00 00 2f 67 75 69 .M........../gui
00000020 64 3d 33 34 45 46 39 34 38 39 30 34 44 42 34 33 d=34EF948904DB43
00000030 37 37 39 31 32 36 33 41 37 34 42 42 46 39 31 32 7791263A74BBF912
00000040 34 42 00 4B.
00000043

name
For example, "Global Addressbook"

UI label:

  • EN: which is a meeting invitation or update
  • DE: die eine Besprechungsanfrage oder -aktualisierung ist

Layout:

uint32_t act_kind = 0xf1;
uint32_t magic = 0;

UI label:

  • EN: from RSS Feeds with <specified text> in the title
  • DE: aus RSS-Feeds mit <angegebener Text> im Titel [sic]

Layout:

uint32_t act_kind = 0xf5;
uint32_t mgc[] = {1, 0};
uint8_t nlen;
if (nlen == 0xff)
uint16_t nlen;
TCHAR name[nlen];

SRestriction:

{RES_OR, {
{RES_CONTENT, RELOP_EQ, PR_MESSAGE_CLASS,
"IPM.Schedule.Meeting.Request"},
{RES_CONTENT, RELOP_EQ, PR_MESSAGE_CLASS,
"IPM.Schedule.Meeting.Canceled"},
}}

UI label:

  • EN: assigned to any category
  • DE: einer beliebigen Kategorie zugewiesen

Layout:

uint32_t act_kind = 0xf6;
uint32_t magic = 0;

SRestriction:

{RES_EXIST, PROP_TAG(PT_MV_STRING8, 0x8002)}

Namedprop: PT_MV_STRING8:PS_PUBLIC_STRINGS:Keywords

Matches if the message has any category set. (This only works for messages received directly through MAPI or as TNEF.)

UI label:

  • EN: from any RSS Feed
  • DE: von beliebigen RSS-Feeds

Layout:

uint32_t act_kind = 0xf7;
uint32_t magic = 0;

SRestriction:

{RES_PROPERTY, RELOP_EQ, PR_MESSAGE_CLASS, ""}

UI label:

  • EN: move it to the <specified> folder
  • DE: diese in den Ordner <Zielordner> verschieben

Layout:

uint32_t act_kind = 0x12c;
uint32_t magic[] = {1, 0};
uint32_t feid_len;
char folder_eid[feid_len];
uint32_t seid_len;
char store_eid[seid_len];
uint8_t fname_len;
if (fname_len == 0xff)
uint16_t fname_len;
TCHAR folder_name[fname_len];
uint32_t magic = 0;

SSRT:

given ACTION *act;
act->acttype = OP_MOVE;
act->ulActionFlavor = 0;
act->actMoveCopy.cbStoreEntryId = @seid_len;
act->actMoveCopy.lpStoreEntryId = @store_eid;
act->actMoveCopy.cbFldEntryId = @feid_len;
act->actMoveCopy.lpFldEntryId = @folder_eid;

The OL2019 UI's left pane arbitrarily restricts folder names to 127 characters by ignoring excess keypresses. The folder property dialog (via context menu) allows longer names, but still arbitrarily restricts folder names to 255 characters by ignoring excess keypresses. Longer names can be set up using MFCMAPI.

This is "move to wastebasket".

UI label:

  • EN: delete it
  • DE: diese löschen

Layout:

uint32_t act_kind = 0x12d;
uint32_t magic = 0;

SSRT:

given ACTION *act;
act->acttype = OP_MOVE;
act->ulActionFlavor = 0;
act->actMoveCopy = <wastebasket>;

UI label:

  • DE: ``diese an <einer Person/öffentlichen Gruppe> weiterleiten" [sic]

UI behavior:

OL2019 offers no way to set the flavor bits FWD_PRESERVE_SENDER...?, etc. (see edkmdb.h).

Layout:

uint32_t act_kind = 0x12e;
uint32_t magic[] = {1, 0};
uint32_t numrcpt;
repeat numrcpt {
XR_PropValArray;
};
uint32_t magic[] = {0, 0};

The propvalarray for a recipient is the same as for a sender (0xcb).

SSRT:

given ACTION *act;
act->acttype = OP_FORWARD;
act->ulActionFlavor = 0;
act->lpadrlist = ...;

Typically 12 props for an SMTP target:

  • PR_ENTRYID
  • PR_DISPLAY_NAME
  • PR_OBJECT_TYPE = 6
  • PR_DISPLAY_TYPE = 0
  • PR_TRANSMITTABLE_DISPLAY_NAME
  • PR_EMAIL_ADDRESS = [email protected]
  • PR_ADDRTYPE = SMTP
  • PR_SEND_RICH_INFO = false
  • PR_SEND_INTERNET_ENCODING = 0
  • PR_RECIPIENT_TYPE = 1 (MAPI_TO)
  • PR_SEARCH_KEY = SMTP:[email protected]
  • PR_RECORD_KEY

Typically 14 props for an EX target:

  • PR_ENTRYID
  • PR_DISPLAY_NAME
  • PR_OBJECT_TYPE = 6
  • PR_DISPLAY_TYPE = 0
  • PR_TRANSMITTABLE_DISPLAY_NAME
  • PR_EMAIL_ADDRESS
  • PR_ADDRTYPE = EX
  • PR_7BIT_DISPLAY_NAME = user#domain.example
  • PR_SMTP_ADDRESS = [email protected]
  • PR_SEND_INTERNET_ENCODING = 0
  • PR_RECIPIENT_TYPE = 1 (MAPI_TO)
  • PR_SEARCH_KEY
  • PR_DISPLAY_TYPE_EX
  • PR_AB_PROVIDERS

UI label:

  • EN: ``reply using <a specific template>"
  • DE: ``diese mit <einer bestimmten Vorlage> beantworten"

UI behavior:

The OL2019 file dialog's text field restricts entering pathnames to 260 characters by ignoring excess keypresses. Furthermore, the UI rejects pathnames longer than 255 characters with a modal error dialog. The pathname from the dialog is used as-is, so there is no automatic conversion between drive letters and \uncpaths.

Layout:

uint32_t act_kind = 0x12f;
uint32_t magic[] = {1, 0};
uint8_t plen;
if (plen == 0xff)
uint16_t plen;
TCHAR pathname[plen];

SSRT:

given ACTION *act;
act->acttype = OP_DEFER_ACTION;
act->ulActionFlavor = 0;
act->actDeferAction.pbData = /* see XR_Begin */;

Action 304 (0x130): Show Outlook notification

Section titled “Action 304 (0x130): Show Outlook notification”

UI label:

  • EN: display <a specific message> in the New Item Alert window
  • DE: Im Benachrichtigungsfenster für neue Elemente <diesen Text> anzeigen

Layout:

uint32_t act_kind = 0x130;
uint32_t magic[] = {1, 0};
uint8_t tlen;
if (tlen == 0xff)
uint16_t tlen;
TCHAR text[tlen];

SSRT:

(Mapped to OP_DEFER_ACTION/XR_Begin)

The OL2019 UI restricts entering messages to 65536 characters by ignoring excess keypresses. When trying to save such a large text, OL will claim Exchange Server has a problem with it. The rule stays deactivated. Deactivated client-side rules are not present in the MAPI Rules Table (PR_ACTIONS), but only in the Rule FAI Message's PR_RW_RULES_STREAM property. Bringing up the rules dialog in OL again shows the message text has been silently truncated to 65535 characters, which suggests that there is no 7B extension to the 3B encoding of length fields.

There are additional limitations with PR_ACTIONS; only some 14539 bytes of the action::actDeferAction::pbData stream are returned by MSMAPI.

UI label:

  • EN: flag message for <action in a number of days>
  • DE: diese mit <einer Aktion in ... Tagen> kennzeichnen

UI behavior:

Only selectable for send rules.

Layout:

uint32_t act_kind = 0x131;
uint32_t magic[] = {1, 0};
uint32_t days;
uint8_t nlen;
if (nlen == 0xff)
uint16_t nlen;
TCHAR action[nlen];
uint32_t magic = 0;

SSRT:

(Not mapped)

UI label:

  • EN: clear the Message Flag
  • DE: die Nachrichtenkennzeichnung löschen

Layout:

uint32_t act_kind = 0x132;
uint32_t magic = 0;

SSRT:

(Mapped to OP_DEFER_ACTION/XR_Begin)

UI label:

  • EN: assign it to the <category> category
  • DE: diese der Kategorie <Kategorie> zuordnen

Layout:

uint32_t act_kind = 0x133;
uint32_t magic[] = {1, 0};
uint8_t clen;
if (clen == 0xff)
uint16_t clen;
TCHAR categories[clen];

SSRT:

(Mapped to OP_DEFER_ACTION/XR_Begin, because OP_TAG resets the property, i.e. would unset all previous categories.)

categories
This is a semicolon-separated string of categories that shall be set on the message. No categories are hereby unset. (Property is PS_PUBLIC_STRINGS:Keywords:PT_MV_UNICODE) For this reason, category names themselves cannot have a semicolon in them. According to MS-OXOCFG, the following characters are also forbidden: U+061B (ARABIC SEMICOLON), U+FE54 (SMALL SEMICOLON) and U+FF1B (FULLWIDTH SEMICOLON).

UI behavior:

The OL2019 UI restricts entering category names by ignoring semicolon keypresses.

Category name-to-color mappings are stored in a FAI message (see ol_category_spec.rst).

UI label:

  • EN: play <a sound>
  • DE: <einen Sound> wiedergeben

UI behavior:

When this element is selected, Outlook also selects "Condition: Machine". However, one can deselect Machine by going back, and then forward again.

SSRT:

(Mapped to OP_DEFER_ACTION/XR_Begin)

The layout is the same as Reply with Template (0x12f), but with act_kind=0x136.

UI label:

  • EN: mark it as <importance>
  • DE: diese als <Priorität> markieren

Layout:

uint32_t act_kind = 0x137;
uint32_t magic[] = {1, 0};
enum : uint32_t {
IMPORTANCE_LOW = 0,
IMPORTANCE_MEDIUM = 1,
IMPORTANCE_HIGH = 2,
} importance;

SSRT:

(Mapped to OP_DEFER_ACTION/XR_Begin, even though OP_TAG could do it.)

UI label:

  • EN: move a copy to the <specified> folder
  • DE: eine Kopie davon in den Ordner <Zielordner> verschieben

The layout is the same as Move (0x12c), but with act_kind=0x139.

SSRT:

The layout is the same as Move (300), but with

act->acttype = OP_COPY;
act->ulActionFlavor = 0;

UI label:

  • EN: notify me when it is read
  • DE: mich benachrichtigen, wenn sie gelesen wurde

UI behavior:

Only selectable for send rules.

Layout:

uint32_t act_kind = 0x13a;
uint32_t magic = 0;

SSRT:

(Not mapped)

UI label:

  • EN: notify me when it is delivered
  • DE: mich benachrichtigen, wenn sie erhalten wurde

UI behavior:

Only selectable for send rules.

Layout:

uint32_t act_kind = 0x13b;
uint32_t magic = 0;

SSRT:

(Not mapped)

UI label:

  • EN: Cc the message to <people or public group>
  • DE: diese an <einer Person/öffentlichen Gruppe> kopieren (Cc) [sic]

UI behavior:

Only selectable for send rules.

The layout is the same as Forward (0x12e), but with act_kind=0x13c.

PR_RECIPIENT_TYPE in the propvalarray still has value MAPI_TO rather than MAPI_CC!

SSRT:

(Not mapped)

UI label:

  • EN: defer delivery by <a number of> minutes
  • DE: diese <eine Anzahl von> Minuten verzögert übermitteln

UI behavior:

Only selectable for send rules.

Layout:

uint32_t act_kind = 0x13e;
uint32_t magic[] = {1, 0};
uint32_t minutes;

SSRT:

(Not mapped)

UI label:

  • EN: stop processing more rules
  • DE: keine weiteren Regeln anwenden

UI behavior:

Understandably, Outlook always ensures this action is at the end of the action list.

Layout:

uint32_t act_kind = 0x142;
uint32_t magic = 0;

SSRT:

PR_RULE_STATE |= ST_EXIT_LEVEL

UI label:

  • EN: redirect it to <people or public group>
  • DE: diese umleiten an <einer Person/öffentlichen Gruppe> [sic]

UI behavior:

The OL2019 UI does not permit mixing this action with other actions not representable as server-side rules.

The layout is the same as Forward (0x12e), but with act_kind=0x144.

SSRT:

The layout is the same as Forward (302), but with

act->acttype = OP_FORWARD;
act->ulActionFlavor = FWD_PRESERVE_SENDER | FWD_DO_NOT_MUNGE_MSG;

UI label:

  • EN: have server reply using <a specific message>
  • DE: diese vom Server mit <einer Nachricht> beantworten

UI behavior:

The OL2019 UI does not permit mixing this action with other actions not representable as server-side rules.

Layout:

uint32_t act_kind = 0x146;
uint32_t magic[] = {1, 0};
uint32_t eidlen;
char eid[eidlen];
uint8_t slen;
if (slen == 0xff)
uint16_t slen;
TCHAR subject[slen];

SSRT:

act->acttype = OP_REPLY;
act->ulActionFlavor = 0;
act->actReply.cbEntryId = @eidlen;
act->actReply.lpEntryId = @eid;

The associated message referenced by eid is stored in the inbox's Associated Contents and has a PR_MESSAGE_CLASS of IPM.Note.Rules.ReplyTemplate.Microsoft.

ulActionFlavor could be STOCK_REPLY_TEMPLATE, but Outlook does not offer this functionality.

UI label:

  • DE: ``diese als Anlage an <einer Person/öffentlichen Gruppe> weiterleiten" [sic]

The layout is the same as Forward (0x12e), but with act_kind=0x147.

SSRT:

The layout is the same as Forward (302), but with

act->acttype = OP_FORWARD;
act->ulActionFlavor = FWD_AS_ATTACHMENT;

UI label:

  • EN: print it
  • DE: diese drucken

UI behavior:

Only selectable for receive rules.

Layout:

uint32_t act_kind = 0x148;
uint32_t magic = 0;

SSRT:

(Mapped to OP_DEFER_ACTION/XR_Begin)

UI label:

  • EN: permanently delete it
  • DE: diese endgültig löschen

UI behavior:

Only selectable for receive rules.

Layout:

uint32_t act_kind = 0x14a;
uint32_t magic = 0;

SSRT:

(Mapped to OP_DEFER_ACTION/XR_Begin, even though it could use OP_DELETE.)

UI label:

  • EN: mark it as read
  • DE: als gelesen markieren

UI behavior:

Only selectable for receive rules.

Layout:

uint32_t act_kind = 0x14c;
uint32_t magic = 0;

SSRT:

(Mapped to OP_DEFER_ACTION/XR_Begin, even though OP_MARK_AS_READ could do it.)

UI label:

  • EN: display a Desktop Alert
  • DE: Desktopbenachrichtigung anzeigen

UI behavior:

Only selectable for receive rules.

Layout:

uint32_t act_kind = 0x14f;
uint32_t magic = 0;

SSRT:

(Mapped to OP_DEFER_ACTION/XR_Begin.)

UI label:

  • EN: flag message for <follow up at this time>
  • DE: Nachricht kennzeichnen für <zu diesem Zeitpunkt nachverfolgen>

UI behavior:

Only selectable for receive rules.

Layout:

uint32_t act_kind = 0x151;
uint32_t magic[] = {1, 0};
enum : uint32_t {
FOLLOWUP_TODAY = 0x1,
FOLLOWUP_TOMORROW = 0x2,
FOLLOWUP_THISWEEK = 0x3,
FOLLOWUP_NEXTWEEK = 0x4,
FOLLOWUP_NODATE = 0x7,
FOLLOWUP_DONE = 0xa,
};
uint8_t fu_name_len;
TCHAR fu_name[fu_name_len];

SSRT:

(Mapped to OP_DEFER_ACTION/XR_Begin.)

UI label:

  • EN: clear message's categories
  • DE: Kategorien der Nachricht löschen

Layout:

uint32_t act_kind = 0x152;
uint32_t magic = 0;

SSRT:

given ACTION *act;
act->acttype = OP_TAG;
act->ulActionFlavor = 0;
act->propTag.ulPropTag = PROP_TAG(PT_MV_UNICODE, 0x8002);

UI label:

  • EN: Apply this rule after the message arrives
  • DE: Nach Erhalt einer Nachricht
  • EN: Apply this rule after I send the message
  • DE: Nach dem Senden einer Nachricht

Layout:

uint32_t act_kind = 0x190;
uint32_t magic[] = {1, 0};
uint32_t flagbits;

SSRT:

All rules in the SSRT are receive rules by definition. The SSRT does not keep send rules.

flagbits

  • 0x01: message was received
  • 0x04: message was sent

UI label:

  • EN: except where my name is in the To box
  • DE: außer wenn mein Name im Feld "An" steht

UI behavior:

Availability: !OL2007 OL2019 Only selectable for receive rules.

Layout:

uint32_t act_kind = 0x1f4;
uint32_t magic = 0;

UI label:

  • EN: except if sent only to me
  • DE: außer wenn sie nur an mich gesendet wurde

UI behavior:

Availability: !OL2007 OL2019 Only selectable for receive rules.

Layout:

uint32_t act_kind = 0xc9;
uint32_t magic = 0;

Condition 502 (0x1f6): Except name not in To

Section titled “Condition 502 (0x1f6): Except name not in To”

UI label:

  • EN: except where my name is in the To box
  • DE: außer wenn mein Name nicht im Feld "An" steht

UI behavior:

Availability: !OL2007 OL2019 Only selectable for receive rules.

Layout:

uint32_t act_kind = 0x1f4;
uint32_t magic = 0;

UI label:

  • EN: except if from <people or public group>
  • DE: außer diese ist von ...

UI behavior:

Availability: !OL2007 OL2019 Only selectable for receive rules.

The layout is the same as From (0xcb), but with act_kind=0x1f7.

UI label:

  • EN: except if sent to <people or public group>
  • DE: außer bei Versand an <einer Person/öffentlichen Gruppe> [sic]

UI behavior:

Availability: OL2007 OL2019 Only selectable for receive rules.

The layout is the same as To (0xcc), but with act_kind=0x1f8.

Condition 505 (0x1f9): Except subject words

Section titled “Condition 505 (0x1f9): Except subject words”

UI label:

  • EN: except if the subject contains <specific words>
  • DE: außer mit <bestimmten Wörtern> im Betreff

UI behavior:

Availability: OL2007 OL2019

The layout is the same as Subject words (0xcd), but with act_kind=0x1f9.

UI label:

  • EN: except if the body contains <specific words>
  • DE: außer mit <bestimmten Wörtern> im Text

UI behavior:

Availability: OL2007 OL2019

The layout is the same as Subject words (0xcd), but with act_kind=0x1fa.

Condition 507 (0x1fb): Except subject or body words

Section titled “Condition 507 (0x1fb): Except subject or body words”

UI label:

  • EN: except if the subject or body contains <specific words>
  • DE: außer mit <bestimmten Wörtern> im Betreff oder Text

UI behavior:

Availability: OL2007 OL2019

The layout is the same as Subject words (0xcd), but with act_kind=0x1fb.

Condition 508 (0x1fc): Except flagged for action

Section titled “Condition 508 (0x1fc): Except flagged for action”

UI label:

  • EN: except if it is flagged for <action>
  • DE: außer wenn sie mit <einer Aktion> markiert ist

UI behavior:

Availability: !OL2007 OL2019

The layout is the same as Flagged for action (0xd0), but with act_kind=0x1fc.

UI label:

  • EN: except if it is marked as <importance>
  • DE: außer wenn mit <Priorität> markiert

UI behavior:

Availability: OL2007 OL2019

The layout is the same as Importance (0xd2), but with act_kind=0x1fe.

UI label:

  • EN: except if it is marked as <sensitivity>
  • DE: außer wenn mit <Vertraulichkeit> markiert

UI behavior:

Availability: OL2007 OL2019

The layout is the same as Sensitivity (0xd3), but with act_kind=0x1ff.

UI label:

  • EN: except if assigned to <category> category
  • DE: außer wenn sie Kategorie <Kategorie> zugeordnet ist

UI behavior:

Availability: OL2007 OL2019

The layout is the same as Category (0xd7), but with act_kind=0x203.

Condition 520 (0x208): Except automated reply

Section titled “Condition 520 (0x208): Except automated reply”

UI label:

  • DE: ``außer es ist eine automatische Antwort"

UI behavior:

Availability: !OL2007 OL2019

Layout:

uint32_t act_kind = 0x208;
uint32_t magic = 0;

UI label:

  • EN: except if it has an attachment
  • DE: außer es ist eine Anlage dabei

UI behavior:

Availability: OL2007 OL2019

Layout:

uint32_t act_kind = 0x20a;
uint32_t magic = 0;

Condition 523 (0x20b): Except form property

Section titled “Condition 523 (0x20b): Except form property”

UI label:

  • EN: except with <selected properties> of documents or forms
  • DE: außer mit Dokument-/Formular-<Eigenschaften>

UI behavior:

Availability: OL2007 OL2019

The layout is the same as Form property (0xd4), but with act_kind=0x20b.

UI label:

  • EN: except with a size <in a specific range>
  • DE: außer mit <einer bestimmten Größe> (KB)

UI behavior:

Availability: OL2007 OL2019

Layout:

uint32_t act_kind = 0x20c;
uint32_t magic[] = {1, 0};
uint32_t min_size_kb;
uint32_t max_size_kb;

UI label:

  • DE: ``außer bei Erhalt <in einem bestimmten Zeitraum>"

UI behavior:

Availability: !OL2007 OL2019

The layout is the same as Date (0xe1), but with act_kind=0x20d.

UI label:

  • EN: except where my name is in the Cc box
  • DE: außer wenn mein Name im Feld "Cc" steht

UI behavior:

Availability: !OL2007 OL2019 Only selectable for receive rules.

Layout:

uint32_t act_kind = 0x20e;
uint32_t magic = 0;

Condition 527 (0x20f): Except name in To or Cc

Section titled “Condition 527 (0x20f): Except name in To or Cc”

UI label:

  • EN: except if my name is in the To or Cc box
  • DE: außer wenn mein Name im Feld "An" oder "Cc" steht

UI behavior:

Availability: !OL2007 OL2019 Only selectable for receive rules.

Layout:

uint32_t act_kind = 0x20f;
uint32_t magic = 0;

Condition 528 (0x210): Except form / message class

Section titled “Condition 528 (0x210): Except form / message class”

UI label:

  • EN: except if it uses the <form name> form
  • DE: außer diese verwendet das Formular <Formularname>

UI behavior:

Availability: OL2007 OL2019

The layout is the same as Form (0xe4), but with act_kind=0x210.

Condition 529 (0x211): Except recipient words

Section titled “Condition 529 (0x211): Except recipient words”

UI label:

  • EN: except with <specified words> in the recipient's address
  • DE: außer mit <bestimmten Wörtern> in der Empfängeradresse

UI behavior:

Availability: OL2007 OL2019

The layout is the same as Subject words (0xcd), but with act_kind=0x211.

Condition 530 (0x212): Except sender words

Section titled “Condition 530 (0x212): Except sender words”

UI label:

  • EN: except with <specified words> in the sender's address
  • DE: außer mit <bestimmten Wörtern> in der Absenderadresse

UI behavior:

Availability: !OL2007 OL2019 Only selectable for receive rules.

The layout is the same as Subject words (0xcd), but with act_kind=0x211.

Condition 531 (0x213): Except header words

Section titled “Condition 531 (0x213): Except header words”

UI label:

  • EN: except if the message header contains <specific words>
  • DE: außer mit <bestimmten Wörtern> im Nachrichtenkopf

UI behavior:

Availability: !OL2007 OL2019 Only selectable for receive rules.

The layout is the same as Subject words (0xcd), but with act_kind=0x213.

UI label:

  • EN: except through the <specified> account
  • DE: außer wenn über Konto <Kontoname> erhalten

UI behavior:

Availability: OL2007 OL2019 When this element is selected, Outlook also selects "Condition: Machine". However, one can deselect Machine by going back, and then forward again.

The layout is the same as Account (0xee), but with act_kind=0x214.

Condition 533 (0x215): Except address book

Section titled “Condition 533 (0x215): Except address book”

UI label:

  • DE: ``außer der Versender ist im Adressbuch <Adressbuchname>"

UI behavior:

Availability: !OL2007 OL2019 Only selectable for receive rules.

The layout is the same as Address book (0xf0), but with act_kind=0x215.

Condition 534 (0x216): Except meeting request

Section titled “Condition 534 (0x216): Except meeting request”

UI label:

  • EN: except if it is a meeting invitation or update
  • DE: außer es handelt sich um eine Besprechungsanfrage oder -aktualisierung

UI behavior:

Availability: OL2007 OL2019

Layout:

uint32_t act_kind = 0x216;
uint32_t magic = 0;

UI label:

  • EN: except if it is from RSS Feeds with <specified text> in the title
  • DE: außer von RSS-Feeds mit '<angegebener Text>' im Titel

UI behavior:

Availability: OL2007 OL2019

The layout is the same as RSS feed (0xf5), but with act_kind=0x219.

Condition 538 (0x21a): Except any category

Section titled “Condition 538 (0x21a): Except any category”

UI label:

  • EN: except if assigned to any category
  • DE: außer bei Zuweisung zu einer beliebigen Kategorie

UI behavior:

Availability: OL2007 OL2019

Layout:

uint32_t act_kind = 0x21a;
uint32_t magic = 0;

Condition 539 (0x21b): Except any RSS feed

Section titled “Condition 539 (0x21b): Except any RSS feed”

UI label:

  • EN: except if from any RSS Feed
  • DE: außer von beliebigen RSS-Feeds

UI behavior:

Availability: OL2007 OL2019

Layout:

uint32_t act_kind = 0x21b;
uint32_t magic = 0;

UI label:

  • EN:?
  • DE: ``vom Formulartyp '<bestimmt>'"

UI behavior:

In OL2019, clicking the <...> hyperlink leads to no dialog and no action. The feature is practically not observable.

UI label:

  • EN: ?
  • DE: ``außer Formulare vom Typ '<bestimmt>'"

UI behavior:

In OL2019, clicking the <...> hyperlink leads to no dialog and no action. The feature is practically not observable.

The layout is presumably the same as Form class.

Perhaps the earliest way inbox rules were defined. The "Inside MAPI" book from 1996 does not mention it (nor does it any other method).

The rules table is a PT_OBJECT property on the inbox folder. To open it:

.. code-block:: c

object_ptr<IExchangeModifyTable> emt; object_ptr<IMAPITable> tbl; inbox->OpenProperty(PR_RULES_TABLE, &IID_IExchangeModifyTable, 0, 0, &~emt); emt->GetTable(&~tbl);

From there on, it is a regular IMAPITable with a number of properties. This table is documented on MSDN, therefore abridged here and limited to notes.

PR_RULE_NAME
Rule display name.

PR_RULE_ID
uint64_t which commonly seems to be 0x01000002 | (rand() << 32). This field is arguably created by the server and a client adding a new rule must not present this property.

PR_RULE_PROVIDER
Observed values: * RuleOrganizer in private store folder standard and extended rules * JunkEmailRule in an private store folder extended rule * Organizer2 * MSFT:TDX Rules in public store folder standard rules * MSFT:TDX OOF Rules

PR_RULE_PROVIDER_DATA
Left undocumented by MSDN, piecewise unraveled in this document.

PR_RULE_SEQUENCE
Integer specifying the order of the rule with respect to others. Apparently, no one could be bothered to insert rules at the right spot and just use PR_ROWID.

In Outlook, right-click on a public folder, select "Properties…", select "Folder Assistant…" (Rule editor). FA allows rules to have only few actions:

  • "Return to sender", which maps to:

    act->acttype = OP_BOUNCE;
    act->ulActionFlavor = 0;
    act->actBounce.scBounceCode = 0x26;

    (scBounceCode follows enum ndr_diag_code.)

  • "Delete", which maps to:

    act->acttype = OP_DELETE;
    act->ulActionFlavor = 0;
  • "Reply with template", which maps to an SSRT OP_REPLY action as shown in section Action 326. Just like with private store rules, STOCK_REPLY_TEMPLATE is not selectable from within Outlook (2021).

  • "Forward", which maps to an SSRT OP_FORWARD action as shown in section Action 302.

Rules are cloned by Outlook to the SSRT if they are enabled and for incoming messages. Conditions and actions supported by the Rule Stream get mapped onto the SSRT fields in various ways.

Properties:

PR_RULE_PROVIDER_DATA
This seems to be a GUID (due to 16 bytes), and this GUID can also be found on FAI message Rule.Version2 as PR_MSG_RULE_PROVIDER_DATA.

Conditions:

See the individual sections on conditions how they get mapped to SSRT SRestrictions. If a rule has been defined without any conditions, or when none of these conditions were mapped to the SSRT, a dummy SRestriction {RES_EXIST, PR_MESSAGE_CLASS} may be attached.

Exceptions:

Exceptions are treated like conditions; they just get wrapped in another RES_NOT container.

Actions:

See the individual sections on actions how they get mapped to SSRT actions. If a rule has been defined with any actions, or when the only action is "stop processing more rules", OP_DEFER_ACTION/XR_Begin is also used.

OOF was originally "Out of Facility", nowadays "Out of Office".

In PR_RULES_TABLE, there will be rows with:

PR_RULE_PROVIDER
Static value consisting of "MSFT:TDX OOF Rules" followed by 32 hex chars [0-9a-f] forming some GUID.

PR_RULE_SEQEUENCE
OL2019 makes them start with 100, effectively putting them after inbox rules, and possibly mixing them for the worse should the normal receive rules exceed 89.

The OOF dialog does not permit many actions at all; basically just the features that map to the edkmdb.h:OP_* values. There are only two extra actions implemented using OP_DEFER_ACTION. The dialog has plenty of bugs and loses information.

uint8_t magic[5] = {0x20, 0x20, 0x20, 0x20, 0x20};
uint8_t actionbytes[2];
char8_t message[]; /* \0-terminated */
char8_t path_and_msg[]; /* \0-terminated */

path_and_msg
e.g. C:\foo.wav;Message here or just C:\foo.wav; for no message.

IPM

  • DE: Generisches Standardformular

IPM.Activity (C*)

  • EN: Journal entry
  • DE: Journaleintrag

IPM.Appointment (C*)

  • EN: Appointment
  • DE: Termin

IPM.Conflict

  • EN: Conflict Message
  • DE: Konfliktnachricht

IPM.Conflict.Resolution.Message

  • EN: Conflict resolution form
  • DE: Formular zur Konfliktbeseitigung

IPM.Contact (C*)

  • EN: Contact
  • DE: Kontakt

IPM.DistList

  • DE: Verteilerliste

IPM.Document

  • DE: Dokument

IPM.InfoPathForm

  • DE: InfoPath-Formular

IPM.Note (C*)

  • EN: Message
  • DE: Nachricht

IPM.Note.Mobile.MMS

  • EN: Multimedia Message
  • DE: Multimedianachricht (MMS)

IPM.Note.Mobile.SMS

  • DE: Textnachricht (SMS)

IPM.Note.RECEIPT.SMIME

  • DE: SMIME-Bestätigung

IPM.Note.Rules.OofTemplate.Microsoft

  • EN: Automatic Replies template
  • DE: Vorlage für automatische Antworten

IPM.Note.Rules.ReplyTemplate.Microsoft

  • EN: Rule reply template
  • DE: Regelantwortvorlage

IPM.Note.SMIME

  • DE: SMIME-Verschlüsselungsformular

IPM.Note.SMIME.MultipartSigned

  • DE: Formular SMIME digital signiert

IPM.Note.Secure

  • DE: Verschlüsselte Nachricht

IPM.Note.Secure.Sign

  • EN: Digitally signed message
  • DE: Nachricht mit digitaler Signatur

IPM.OLE.CLASS.{00061055-0000-0000-C000-000000000046}

  • DE: Ausnahme

IPM.Outlook.Recall

  • EN: Recall Message Form
  • DE: Formular zum Nachrichtenrückruf

IPM.POST (C*)

  • DE: Bereitstellen

IPM.POST.RSS (C*)

  • EN: RSS Article
  • DE: RSS-Artikel

IPM.Recall

  • EN: Message Recall Report
  • DE: Nachrichtenrückrufbericht

IPM.Remote

  • EN: Remote
  • DE: Remote

IPM.Resend

  • EN: Resend
  • DE: Noch mal senden

IPM.Schedule.Meeting.Canceled

  • EN: Meeting Cancellation
  • DE: Besprechungsabsage

IPM.Schedule.Meeting.Request (C*)

  • EN: Meeting Request
  • DE: Besprechungsanfrage

IPM.Schedule.Meeting.Request.Neg

  • EN: Decline Meeting Response
  • DE: Besprechung ablehnen

IPM.Schedule.Meeting.Resp.Pos

  • EN: Accept Meeting Response
  • DE: Besprechungseinladung annehmen

IPM.Schedule.Meeting.Resp.Tent

  • DE: Besprechungszusage mit Vorbehalt

IPM.Sharing

  • EN: Sharing Request
  • DE: Freigabeanfrage

IPM.StickyNote

  • EN: Note
  • DE: Notiz

IPM.Task (C*)

  • DE: Aufgabe

IPM.TaskRequest (C*)

  • DE: Aufgabenanfrage

IPM.TaskRequest.Accept

  • DE: Aufgabe annehmen

IPM.TaskRequest.Decline

  • DE: Aufgabe ablehnen

IPM.TaskRequest.Update

  • DE: Aufgabe aktualisieren

REPORT

  • DE: Bericht

Custom forms may be created from the classes/forms designated C*. The resulting message class will use that prefix. For example, deriving from the IPM.Note form and saving it under the name MyForm will make it available under the class name IPM.Note.MyForm.