2.1.3.4 Encapsulated Message and Attachment Properties

The attMsgProps and attAttachment attributes, as specified in sections section 2.1.3.3.21 and section 2.1.3.3.23 respectively, are special in that they are used to encode any message or attachment property that does not have a counterpart in the set of existing TNEF-defined attributes. The attribute data is a counted set of message or attachment properties laid end-to-end. The format of this encoding, which allows for any set of message or attachment properties, is as follows.

  
 ; Attributes containing encapsulated properties:
  
 ; attMsgProps - Maps to and from an arbitrary set of message properties.
 MsgPropsData = MsgPropertyList
  
 ; attRecipTable - Maps to and from PidTagMessageRecipients,
 ; as specified in [MS-OXCMSG] section 2.2.1.47.
 ; Number of table rows followed by the rows.
 RecipTableData = NumRows *RecipRow
  
 NumRows = UINT32
 RecipRow = MsgPropertyList
  
 ; attAttachment – Maps to/from an arbitrary set of properties for a single attachment.
 AttachPropsData = MsgPropertyList
  
 MsgPropertyList = MsgPropertyCount *MsgPropertyValue
 MsgPropertyCount = UINT32
  
 MsgPropertyValue = MsgPropertyTag MsgPropertyData
 MsgPropertyTag = MsgPropertyType MsgPropertyId [NamedPropSpec]
  
 ; This property MUST be present when MsgPropertyId is >= 0x8000 (the minimum value
 ; of property ID for named properties, as specified in
 ; [MS-OXPROPS] section 1.3.3).
 NamedPropSpec = PropNameSpace PropIDType PropMap
  
 ; Contains a GUID, as specified in [MS-OXCDATA], to specify the namespace.
 ; The TNEF Writer obtains this value by using the RopGetNamesFromPropertyIDs ROP,  
 ; as specified in [MS-OXCROPS] section 2.2.8.2.
 PropNameSpace = GUID
 PropIDType = IDTypeNumber / IDTypeString
 PropMap = PropMapID / PropMapString
  
 IDTypeNumber = %x00.00.00.00
 IDTypeString = %x01.00.00.00
  
 ; Used if PropIDType is IDTypeNumber. Contains a number, as specified in
 ; [MS-OXPROPS] section 1.3.4.2, that is used to identify the property within the namespace.
 PropMapID = UINT32
  
 ; Used if PropIDType is IDTypeString. Contains a length, then a
 ; UTF-16LE encoded Unicode string.
 ; The length is the length of the UTF-16LE encoded Unicode string 
 ; (including the terminating 2-byte null character). 
 ; Optional padding to UINT32 boundary.
 ; The TNEF Writer obtains this value by using the RopGetNamesFromPropertyIds
 ; ROP, as specified in [MS-OXCROPS] section 2.2.8.2.
 PropMapString = UINT32 *UINT16 %x00.00 [PropMapPad]
  
 ; Padding for a UTF-16LE encoded Unicode string to achieve a
 ; multiple of 4 bytes in length.
 ; The TNEF Writer MUST use zero bytes and the TNEF Reader
 ; MUST permit non-zero bytes.
 ; SHOULD be either 0 or 2 bytes.
 PropMapPad=*1UINT16
  
 MsgPropertyType = TypeUnspecified / TypeNull / TypeInt16 / TypeInt32 /
  TypeFlt32 / TypeFlt64 / TypeCurrency / TypeAppTime / TypeError /
  TypeBoolean / TypeObject / TypeInt64 / TypeString8 / TypeUnicode /
  TypeSystime / TypeCLSID / TypeBinary / TypeMVInt16 / TypeMVInt32 /
  TypeMVFlt32 / TypeMVFlt64 / TypeMVCurrency / TypeMVAppTime /
  TypeMVSystime / TypeMVString8 / TypeMVBinary / TypeMVUnicode /
  TypeMVCLSID / TypeMVInt64
  
 ; An arbitrary value that corresponds to the property. For named properties, the value is >= 0x8000 (as specified in [MS-OXPROPS] section 1.3.3).
 MsgPropertyId = UINT16
  
 TypeUnspecified = %x00.00
  
 TypeNull = %x01.00
  
 ; Signed 16-bit value = INT16.
 TypeInt16 = %x02.00
 TypeMVInt16 = %x02.10
  
 ; Signed 32-bit value = INT32.
 TypeInt32 = %x03.00
 TypeMVInt32 = %x03.10
  
 ; Signed 32-bit floating point= FLOAT.
 TypeFlt32 = %x04.00
 TypeMVFlt32 = %x04.10
  
 ; 64-bit floating point= DOUBLE.
 TypeFlt64 = %x05.00
 TypeMVFlt64 = %x05.10
  
 ; Signed 64-bit int = OLE CURRENCY type.
 TypeCurrency = %x06.00
 TypeMVCurrency = %x06.10
  
 ; Application time= OLE DATE type.
 TypeAppTime = %x07.00
 TypeMVAppTime = %x07.10
  
 TypeError = %x0A.00
  
 ; 16-bit Boolean (non-zero = TRUE)
 TypeBoolean = %x0B.00
  
 ; Embedded object on a property.
 TypeObject = %x0D.00
  
 ; 8-byte signed integer= INT64.
 TypeInt64 = %x14.00
 TypeMVInt64 = %x14.10
  
 ; 8-bit character string with terminating null character.
 TypeString8 = %x1E.00
 TypeMVString8 = %x1E.10
  
 ; UTF-16LE or variant character string with terminating 2-byte null character.
 TypeUnicode = %x1F.00
 TypeMVUnicode = %x1F.10
  
 ; FILETIME (a PtypTime value, as specified in [MS-OXCDATA] section 2.11.1)
 TypeSystime = %x40.00
 TypeMVSystime = %x40.10
  
 ; OLE GUID
 TypeCLSID = %x48.00
 TypeMVCLSID = %x48.10
  
 ; Uninterpreted BLOB.
 TypeBinary = %x02.01
 TypeMVBinary = %x02.11
  
 ; MsgPropertyData varies by property type. Individual property values 
 ; are formatted as specified in [MS-OXCDATA] section 2.11, with 
 ; padding as specified in this document.
  MsgPropertyData = PropertyScalarContent / PropertyMultiScalarContent /
  PropertyMultiVariableContent
  
 ; Scalars – Types Int16, Int32, Flt32, Flt64, Currency, AppTime,
 ; Bool, Int64, Systime, CLSID
 ; The data for the particular property is written to the stream and if necessary,
 ; padded with bytes (which SHOULD be zero) to achieve a multiple of 4-bytes in length.
 PropertyScalarContent = MsgPropertyContent [PropertyPad]
  
 ; PropertyPad – between 0 and 3 zero-filled bytes, added to the streamed
 ; property values to achieve 4-byte boundary. The TNEF Writer MUST use zero bytes
 ; and the TNEF Reader MUST permit non-zero bytes. These pad bytes MUST be counted
 ; in the checksum of the containing attribute.
 PropertyPad=*3ZERO
 ZERO= %x00
  
 ; Multi-value Scalars – Types MVInt16, MVInt32, MVFlt32, MVFlt64, MVCurrency,
 ; MVAppTime, MVInt64, MVSystime, MVCLSID
 ; The number of values for the property is written to the stream as a 4-byte
 ; value, then the data for each value is written to the stream and if need
 ; be, padded with bytes (which SHOULD be zero) to achieve a multiple of 4 bytes in length.
 PropertyMultiScalarContent = PropertyContentCount *PropertyScalarContent
 PropertyContentCount = UINT32
  
 ; Variable-length – Types Unicode, String8, Object, Binary.
 ; These are handled as a special case of Multi-Variable-Length with the number of values=1.
  
 ; Multi-Variable-length – Types MVUnicode, MVString8, MVBinary
 ; The number of values for the property is written to the stream as a 4-byte value. ; Then, for each value, the size of the property is written to the stream as a
 ; 4-byte value, then the data for the property is written to the stream and, if
 ; necessary, padded with zero bytes to achieve a multiple of 4 bytes in length.
  
 PropertyMultiVariableContent = MsgPropertyCount 1*PropertyVariableContent
 MsgPropertyCount = UINT32
  
 ; The size of the property is written to the stream as a 4-byte value, then the data
 ; for the property is written to the stream and if necessary, padded with zero bytes
 ; to achieve a multiple of 4 bytes in length. The size includes the Interface
 ; Identifier at the beginning of the value stream for an object but does not include
 ; the padding bytes.
 ;
 ; If the property is of type PtypObject, as specified in 
 ; [MS-OXCDATA] section 2.11.1, 
 ; the value-size is followed by the Interface Identifier of the object, then the serialized 
 ; stream of the data of the object. Only the Interface Identifier values 
 ; %x0B.00.00.00.00.00.00.00.C0.00.00.00.00.00.00.46, 
 ; %x0C.00.00.00.00.00.00.00.C0.00.00.00.00.00.00.46, and the Interface Identifiers of
 ; Message objects are supported. The size of the Interface Identifier is 
 ; included in the calculation of value-size.
 ;
 ; If the object is an attached message (that is, it has a property type of  
 ; PtypObject (as specified in [MS-OXCDATA] section 2.11.1) and an
 ; Interface Identifier %x07.03.02.00.00.00.00.00.C0.00.00.00.00.00.00.46,
 ; (that of a Message object), the value data is encoded as an embedded TNEF
 ; stream (that is, a complete TNEF stream as defined by this specification).
  
 PropertyVariableContent = MsgPropertySize MsgPropertyContent [PropertyPad]
 MsgPropertySize = UINT32