An Outlook item is a set of MAPI properties, each a 16-bit property ID and a 16-bit type. [MS-OXMSG] says how they are stored in the compound file. This page was checked on 2026-11-12 against [MS-OXMSG], with the types from [MS-OXCDATA], the tags from [MS-OXPROPS], flags and attachment methods from [MS-OXCMSG], recipient types from [MS-OXOMSG] and compressed RTF from [MS-OXRTFCP]. Numbers are little-endian.
Storages and streams
| Name | Kind | Holds |
|---|---|---|
__properties_version1.0 | stream | The property stream of the object it is in. |
__substg1.0_IIIITTTT | stream | One variable-size property: ID IIII and type TTTT, in upper-case hex. |
__substg1.0_IIIITTTT-NNNNNNNN | stream | Value N of a multi-valued string or binary property; the base stream holds the lengths. |
__recip_version1.0_#NNNNNNNN | storage | One recipient, numbered in hex from 0, with its own properties; at most 2,048. |
__attach_version1.0_#NNNNNNNN | storage | One attachment; at most 2,048. |
__substg1.0_3701000D | storage | Inside an attachment: an embedded message (method 5), laid out like a whole .msg but without its own named property map; or, for method 6, storage whose layout the owning application defines. |
__nameid_version1.0 | storage | The named property map; top level only, covering embedded messages too. |
Strings are all Unicode (001F) when PidTagStoreSupportMask
has STORE_UNICODE_OK (0x00040000) set, and otherwise all
8-bit (001E); one message never mixes them. An embedded message has its
own Unicode state.
Property stream
A header, then one 16-byte entry per property.
| Header of | Size | Fields |
|---|---|---|
| Top-level message | 32 | 8 reserved; next recipient ID (4); next attachment ID (4); recipient count (4); attachment count (4); 8 reserved. |
| Embedded message | 24 | The same without the last 8 reserved bytes. |
| Recipient or attachment | 8 | Reserved. |
| Entry offset | Size | Field |
|---|---|---|
0 | 4 | Property tag: type in the low 16 bits, ID in the high 16. |
4 | 4 | Flags: 1 mandatory, 2 readable, 4 writable. |
8 | 8 | Fixed-size types: the value, padded with zeros to 8 bytes. Other types: a 4-byte size, then 4 reserved; the value is in its __substg1.0_ stream. The size is the stream’s size, plus 2 for 001F or 1 for 001E (the terminating zero, which the stream leaves out); for variable-size multi-valued types it is the size of the length stream. For an embedded message or storage attachment the size is FFFFFFFF and the reserved field is 1 (method 5) or 4 (method 6). |
Property types
| Type | Name | Stored |
|---|---|---|
0002 | PtypInteger16 | 2 bytes, in the entry |
0003 | PtypInteger32 | 4 bytes, in the entry |
0004 | PtypFloating32 | In the entry |
0005 | PtypFloating64 | In the entry |
0006 | PtypCurrency | 64-bit × 10,000, in the entry |
0007 | PtypFloatingTime | Days since 30 December 1899, in the entry |
000A | PtypErrorCode | In the entry |
000B | PtypBoolean | 1 byte, in the entry |
000D | PtypObject | A storage |
0014 | PtypInteger64 | In the entry |
001E | PtypString8 | Stream, 8-bit text in an externally given encoding |
001F | PtypString | Stream, UTF-16LE |
0040 | PtypTime | FILETIME, in the entry |
0048 | PtypGuid | Stream, 16 bytes |
0102 | PtypBinary | Stream |
1002, 1003, 1004, 1005, 1006, 1007, 1014, 1040, 1048 | Multi-valued fixed types | Stream: the values one after another |
101E, 101F, 1102 | Multi-valued strings and binaries | Stream of lengths (4 bytes each for strings, 8 for binaries), then one stream per value |
Named properties
Property IDs 8000 and above are named properties, mapped per file. The
__nameid_version1.0 storage holds three streams:
__substg1.0_00020102: GUIDs, 16 bytes each.__substg1.0_00030102: entries, 8 bytes each. Bytes 0–3: the numeric name, or an offset into the string stream. Bytes 4–7: bit 0 the kind (0 numeric, 1 string); bits 1–15 the GUID index (1 =PS_MAPI, 2 =PS_PUBLIC_STRINGS, 3 and up = GUID stream entry index − 3); bits 16–31 the property index. Entry i has property ID8000 + i.__substg1.0_00040102: strings, each a 4-byte length then UTF-16LE, padded to a multiple of 4.
For looking up a name, up to 31 further streams __substg1.0_XXXX0102
hold 8-byte entries (the numeric name or the CRC-32 of the string name, then the
same index-and-kind field). The stream ID XXXX is
0x1000 + (ID XOR (GUID index << 1)) MOD 0x1F for numeric names
and 0x1000 + (CRC XOR (GUID index << 1 | 1)) MOD 0x1F for string
names.
Compressed RTF
[MS-OXRTFCP].
A 16-byte header: compressed size (4, counting from byte 4), raw size
(4), type (4: LZFu compressed, MELA not compressed) and a
CRC-32 of the compressed data (4, 0 for MELA). The data is LZ77 with a 4,096-byte
dictionary that starts filled with a fixed RTF prologue string: each control byte
gives 8 flags, low bit first; a 0 flag is a literal byte, a 1 flag a 2-byte
big-endian reference of a 12-bit dictionary offset and a 4-bit length − 2. A
reference to the current write position ends the data.