OpenChange Property Files 2.0 API Documentation

- Main Page
- Files
- Examples

OpenChange Property File (OCPF)

# OpenChange Property File (OCPF)

# Contents

- Revision History
- 1. Introduction
- 2. Purpose and Scope
- 3. Limitations and Bugs
- 4. Syntax
- 5. Top Level Keywords
  - 5.1. TYPE
  - 5.2. FOLDER
  - 5.3. SET
  - 5.4. OLEGUID
  - 5.5. RECIPIENT
  - 5.6. PROPERTY section
  - 5.7. NPROPERTY section
- 6. Known Properties
  - 6.1. Property Name
  - 6.2. Property Tag
- 7. Named Properties
  - 7.1. OOM
  - 7.2. MNID_ID
  - 7.3. MNID_STRING
- 8. Supported Property Types
  - 8.1. PT_BOOLEAN
  - 8.2. PT_SHORT
  - 8.3. PT_LONG
  - 8.4. PT_I8
  - 8.5. PT_DOUBLE
  - 8.6. PT_STRING8
  - 8.7. PT_UNICODE
  - 8.8. PT_SYSTIME
  - 8.9. PT_MV_STRING8
  - 8.10. PT_MV_UNICODE
  - 8.11. PT_BINARY
  - 8.12. PT_MV_BINARY
  - 8.13. PT_MV_LONG
- 9. Comments
- 10. OCPF and openchangeclient
  - 10.1. ocpf_syntax
  - 10.2. ocpf_sender
  - 10.3 ocpf_dump

## Revision History

Date | Revision Number | Author | Revision Content
27/11/10 | 0.7 | Brad Hards | Add PT_DOUBLE support. Update PT_I8 description.
27/11/10 | 0.6.1 | Brad Hards | Update bug tracker link, minor rewording
25/06/10 | 0.6 | Julien Kerihuel | Add PT_MV_BINARY, PT_MV_LONG and PT_MV_UNICODE support. Update PT_BINARY description.
01/04/08 | 0.5 | Julien Kerihuel | Add RECIPIENT support
29/03/08 | 0.4 | Julien Kerihuel | Add PT_UNICODE support and ocpf_dump option
06/03/08 | 0.3 | Julien Kerihuel | Add PT_BINARY and Streams support
05/03/08 | 0.2 | Julien Kerihuel | Improve PT_MV_STRING8 support
03/03/08 | 0.1 | Julien Kerihuel | Initial Revision

## 1. Introduction

OCPF stands for OpenChange Property Files. This is a tiny file format designed for scripting and which facilitates third-party applications interaction and developers work using OpenChange. The main objective of OCPF is to offer the possibility to go beyond OpenChange tools default properties and create a custom message with user-defined fields.

## 2. Purpose and Scope

OCPF is designed to be used in various kind of applications and for different purposes:

- Research on properties: OpenChange developers have often requested for an easy way to test properties and properties values. Prior to OCPF, developers had to write an application linked with libmapi and compile it so that they could test properties. Moreover, adding new named properties in trunk required commit permission to OpenChange source repository. OCPF solves this issue and allow developers to write OCPF files with custom properties that they can send using OpenChange tools. Furthermore OCPF will provide the community a convenient way to agree on a particular property.

- Web Applications: OCPF offers a scripted language with substitution variables which makes it possible to use OCPF templates and use OCPF in conjunction with Web Forms. Since OCPF API supports the parsing of multiple files, developers can plan to have a file with variable declarations and a separate OCPF template that just specifies variables.

- Backup/Restore: OCPF format may offer an easy way for a restore/backup application to dump to the local filesystem and restore messages on Exchange server. Furthermore, substitution of variables can possibly be used to maintain the new hierarchy, such as changing folders ID across Exchange servers and help migrating database from a server to another.

## 3. Limitations and Bugs

OCPF is a pretty new library and it currently has a some limitations:

- It only supports a very limited set of property types
- It doesn't support attachment yet

These limitations will be removed in later versions of OCPF.

If you find bugs, limitations or encounter issues while using the OCPF library, please consider reporting them on http://tracker.openchange.org. (Note: registration is required to create new tickets).

For questions about its usage or about libocpf development, please post on the OpenChange devel mailing-list.

## 4. Syntax

The general OCPF syntax is pretty basic. It mostly consists of top-level keywords, sections and properties types.

## 5. Top Level Keywords

### 5.1 TYPE

- Format:

  TYPE STRING

- Description:

  This keyword specifies the message class of the message. Users can either specify their custom type or use on of the following standard values:

  - "IPM.Appointment"
  - "IPM.Contact"
  - "IPM.Journal"
  - "IPM.Note"
  - "IPM.StickyNote"
  - "IPM.Task"
  - "IPM.Post"

- Note:

  TYPE can only be defined once and takes a string value as parameter. String values must be quoted otherwise a syntax error will be displayed on output.

- Example:
  TYPE "IPM.Appointment"

### 5.2 FOLDER

- Format:
  FOLDER STRING
  FOLDER PT_I8
  FOLDER VAR

- Description:

  This keyword defines the destination folder of the message. Users can either specify a default folder using the string value or a custom folder ID using its PR_FID value. It is also possible to substitute the value with a variable, but it is limited to PT_I8 values.

  When FOLDER is set with a PT_I8 custom value and the ocpf_OpenFolder public function used, it can be set to any folder identifier within the message store. The function will loop over mailbox folders until it finds the folder with the given folder ID and opens it.

  Possible STRING values:

  - olFolderTopInformationStore
  - olFolderDeletedItems
  - olFolderOutbox
  - olFolderSentMail
  - olFolderInbox
  - olFolderCommonView
  - olFolderCalendar
  - olFolderContacts
  - olFolderJournal
  - olFolderNotes
  - olFolderTasks

- Note:

  FOLDER can only be defined once.

- Examples:

  FOLDER "olFolderCalendar"

  or

  FOLDER D0x9504000000000001

  or

  SET $folder_id = D0x9504000000000001
  FOLDER $folder_id

### 5.3. SET

- Format:
  SET VAR = PROPVALUE

- Description:

  This keyword registers a variable named VAR and sets its value to PROPVALUE. Variables must be prefixed with a dollar sign ($) and their value can be set to any supported property type. See section on property values for further information.

- Note:

  SET can be used as many times as needed by the user, however VAR name must remain unique. When a variable name is registered for the second time, the OCPF parser displays a warning on the standard output and skips the assignment.

- Example:
  SET $var1 = 0xdeadbeef
  SET $var2 = "Hello World"
  SET $var3 = T2008-03-06 23:30:00

### 5.4. OLEGUID

- Format:
  OLEGUID IDENTIFIER STRING

- Description:

  This keyword registers an OLEGUID couple (IDENTIFIER and STRING value) that can then be used when declaring named properties (see NPROPERTY). OLEGUID keyword takes two parameters: first the name, used with named properties (PSETID_Appointment, PS_PUBLIC_STRINGS etc.) and secondly a string representing a GUID value.

- Note:

  OLEGUID are identified by their IDENTIFIER and STRING. Users can't register the same OLEGUID IDENTIFIER or STRING twice. If such case occurs, a warning message will be displayed on stdout.

- Example:
  OLEGUID PSETID_Appointment "00062002-0000-0000-c000-000000000046"
  [...]
  NPROPERTY {
  OOM:Label:PSETID_Appointment = T2008-03-06 23:30:00
  [...]

### 5.5. RECIPIENT

- Format:
  RECIPIENT TO STRING;STRING;STRING
  RECIPIENT CC STRING;STRING
  RECIPIENT BCC STRING

- Description:

  This keyword declares recipients. RECIPIENT is followed by a recipient type (TO, CC or BCC) and a set of STRING (recipients) separated with semicolon.

- Example:
  RECIPIENT TO "recipient1";"recipient2";"recipient3"
  RECIPIENT CC "recipient4"
  RECIPIENT BCC "recipient5@remote.corp";"recipient6"

### 5.6. PROPERTY section

- Format:
  PROPERTY {
  [...]
  };

- Description:

  This keyword declares a known property section. PROPERTY is followed by an opening brace, a set of property declarations and is ended with a closing brace and semicolon. This section only recognizes properties as described in 6. Known properties.

- Note:

  While we suggest keeping a single PROPERTY section, nothing prevents the user from declaring as many PROPERTY sections as needed.

- Example:
  PROPERTY {
  PR_SUBJECT = "Hello World"
  0x1000001e = "Sample body content"
  };

### 5.7. NPROPERTY section

- Format:
  NPROPERTY {
  [...]
  };

- Description:

  This keyword declares a named property section. NPROPERTY is followed by an opening brace, a set of named properties declarations and is ended with a closing brace and semicolon. This section only recognizes named properties as described in 7. Named Properties.

- Note:

  While we suggest keeping a single NPROPERTY section, nothing prevents the user from declaring as many NPROPERTY sections as needed.

- Example:
  NPROPERTY {
  OOM:Start:PSETID_Appointment = T2008-03-06 22:00:00
  OOM:Location:PSETID_Appointment = "Home Sweet Home"
  /* Meeting Status */
  MNID_ID:0x8217:PSETID_Appointment = 0;
  };

## 6. Known Properties

A known properties is any property where the value doesn't change across Exchange servers and versions. Known properties can only be registered within a PROPERTY section (See 5.6 PROPERTY section). Known properties have the same general syntax:

IDENTIFIER = [PROPVALUE | VAR]
INTEGER = [PROPVALUE | VAR]

OCPF lets the user define known properties using two different methods: property names or property tags.

Please note that OCPF doesn't check whether the value associated with the property matches the property type. For the moment it is the developer's responsibility to ensure that the property type matches its value.

### 6.1. Property Names

        Property Names are defined with an IDENTIFIER which must match
        one already registered in libmapi/conf/mapi-properties. For
        example:

PR_SUBJECT = "Hello World"
PR_START_DATE = T2008-03-06 22:00:00
PR_PRIORITY = 2

### 6.2. Property Tags

        Property Tags are the other way to set a property. This is an
        integer value represented using hexadecimal notation and
        which has two parts: the upper 16 bits are the property ID and
        the lower 16 bits are the property type.

        While users may prefer to use the property name notation for
        declaration, libmapi/conf/mapi-properties remains incomplete
        and there may be cases where you need to use the property tag
        notation. The example below sets properties described in
        previous example using their property tag notation.

0x0037001e = "Hello World"
0x00600040 = T2008-03-06 22:00:00
0x00260003 = 2

.

## 7. Named Properties

The OCPF syntax for different kind of named properties is quite generic. It supports each of the three kinds of property (OOM, MNID_ID, MNID_STRING) and can set known named properties (those listed in libmapi/conf/mapi-named-properties) or register new named properties (except OOM properties).

The types of properties, and how they can be used, are described below.

### 7.1. OOM

OOM stands for Outlook Object Model and is a friendly name associated to a named property. It has no meaning to Exchange, but it can be useful for OpenChange or MAPI developers.

OOM are human readable shortcuts for most named properties and OOM values are are considered reliable. This is the reason why OOM can only be used if it exists in libmapi/conf/mapi-named-properties. This method - in our opinion - is the best method to guarantee developers a common and validated mapi-named-properties file.

Theorically, property names can have the same OOM, property ID (MNID_ID) or name (MNID_STRING). The only way to guarantee named property uniqueness is to associate its value with a OLEGUID.

OLEGUID needs to be registered before they can be used with named properties. See 5.4 OLEGUID for more information on how to register a OLEGUID.

OOM named properties have the following syntax:

OOM:IDENTIFIER:IDENTIFIER = [PROPVALUE | VAR]

The first IDENTIFIER represents the OOM value while the second one represents the OLEGUID. Note that identifiers are not enclosed with quotes. Below are some OOM assignments examples:

OOM:Label:PSETID_Appointment = 9
OOM:End:PSETID_Appointment = $end_date
OOM:Private:PSETID_Common = B"true"

### 7.2. MNID_ID

Named properties that Exchange converts using their property ID (16 bits) are known as MNID_ID named property kind. OCPF provides two different ways to define MNID_ID. It can either be a new named property or an existing one which wouldn't have any associated OOM.

MNID_ID named property kind has the following syntax:

MNID_ID:INTEGER:PROPTYPE:IDENTIFIER = [PROPVALUE | VAR]
MNID_ID:INTEGER:IDENTIFIER = [PROPVALUE | VAR]

If the MNID_ID named property doesn't exist within libmapi/conf/mapi-named-property then you must specify its property type.

As described in the example below, the main difference between known and custom MNID_ID named properties is whether or not we specify its property type. If your MNID_ID property has not been referenced within libmapi/conf/mapi-named-property, then you must supply its property type, otherwise you can skip it.

Note: PROPTYPE can be any of the values described in 8. Supported Property Types .

MNID_ID:0x8501:PT_LONG:PSETID_Common = $reminder /* Reminder */
MNID_ID:0x8217:PSETID_Appointment = 0 /* MeetingStatus */

### 7.3. MNID_STRING

Exchange also supports named properties which do not have a property ID but are described using property names. These named properties are known as MNID_STRING named property kind and Exchange maps these names to a temporary property type.

MNID_STRING named property kind has the following syntax:

MNID_STRING:STRING:IDENTIFIER = [PROPVALUE | VAR]
MNID_STRING:STRING:PROPTYPE:IDENTIFIER = [PROPVALUE | VAR]

MNID_STRING difference between known and custom is the same as MNID_ID one. If the MNID_STRING property doesn't exist in libmapi/conf/mapi-named-properties, then users have to supply its PROPTYPE.

NOTE: PROPTYPE can be any of the value described in 8. Supported Property Types .

Considering the behavior described above, we could set the "Keywords" MNID_STRING named property using any of the following example:

MNID_STRING:"Keywords":PS_PUBLIC_STRINGS = {"one", "two" , "three" }
MNID_STRING:"Keywords":PT_MV_STRING8:PS_PUBLIC_STRINGS = {"one", "two" , "three" }

## 8. Supported Property Types

### 8.1. PT_BOOLEAN

OCPF uses the following format for BOOLEAN values:

B"true"
B"false"

### 8.2. PT_SHORT

OCPF can use any of the following formats for SHORT values:

S0x1234
S32

The short integer can either be in hexadecimal of decimal notation but must be prefixed with a "S" to specify this is a short integer value. If you omit to specify the "S", mismatch property type/value errors will occur while sending the message.

### 8.3. PT_LONG

OCPF can use any of the following formats for PT_LONG values:

0xdeadbeef
L0xdeadbeef
32

The integer can either be in hexadecimal or decimal notation or prefixed with a "L" to specify this is long value. If you use the hexadecimal notation consider using the 'L' prefixed form since other form may disappear in further versions.

### 8.4. PT_I8

OCPF uses the following format for PT_I8 (uint64_t) values:

D0x9504000000000001

### 8.5. PT_DOUBLE

OCPF uses an exponent format for floating point (double) number, as shown in this example:

F3.1415e+03

### 8.6. PT_STRING8

OCPF defines a string as a set of characters (A-Za-z0-9_) enclosed with double quotes:

"I am a STRING"

### 8.7. PT_UNICODE

OCPF defines a unicode string as a set of characters enclosed with double quotes and prefixed with W:

W"I am a UNICODE string"

### 8.8. PT_SYSTIME

OCPF defines date using the following format string:

TYYYY-MM-DD HH:MM:SS

Dates are prefixed with a 'T' character and its content is represented with the syntax below:

- YYYY: year
- MM: month
- DD: day
- HH: hours
- MM: minutes
- SS: seconds

T2008-03-06 22:30:00 /* 2008, 6th of March 10:30:00PM */

### 8.9. PT_MV_STRING8

PT_MV_STRING8 are arrays ("multiple values") of strings. OCPF defines PT_MV_STRING8 property values as STRING property values separated by commas and enclosed within braces.

{ STRING, STRING, ..., STRING }

At least one STRING property value is required to create a valid PT_MV_STRING8 property. If two or more STRING property values are set, then they must be separated with comma.

{ "single multi-string value" }
{ "one" , "two", "three", "owned" }

### 8.10. PT_MV_UNICODE

PT_MV_UNICODE are arrays ("multiple values") of unicode strings. OCPF defines PT_MV_UNICODE property values as UNICODE property values separated by commas and enclosed within braces.

{ UNICODE, UNICODE, ..., UNICODE }

At least one UNICODE property value is required to create a valid PT_MV_UNICODE property. If two or more UNICODE property values are set, then they must be separated with comma.

{ W"single multi-unicode value" }
{ W"four", W"five", W"six" }

### 8.11. PT_BINARY

PT_BINARY are blobs of data. OCPF defines PT_BINARY property values using two different methods. This can either be raw/inline blob of data or filename/external.

If users wish to add raw data blob for a given property, they need to enclose UINT8 (from 0x00 to 0xFF) values within braces. However many cases occur where the data blob is large (such as HTML content; PR_HTML has PT_BINARY property type). In such cases, users may rather prefer to write an external file and specify a filename.

{ UINT8 UINT8 [...] UINT8 }
< STRING >

Note that if the blob of data (raw or pointed by filename) is too large to fit in the property values array, then OCPF will automatically open a stream for the property and write its data in the stream.

PR_HTML = { 0x48 0x65 0x6c 0x6c 0x6f } /* Hello */
PR_HTML = <"/tmp/sample.html">

### 8.12. PT_MV_BINARY

PT_MV_BINARY are arrays ("multiple values") of PT_BINARY blobs. OCPF defines PT_MV_BINARY propery values as PT_BINARY property values separated by commas and encloses within braces.

{ PT_BINARY, PT_BINARY, PT_BINARY }

At least one PT_BINARY property value is required to create a valid PT_MV_BINARY property. If two or more PT_BINARY are set, then they must be separated with comma.

{ {0x48 0x65 0x6c 0x6c 0x6f}, {0x77 0x6f 0x72 0x6c 0x64}, { 0x21 } } /* Hello world ! */

Note that current implementation does not support the following PT_BINARY format:

< STRING >

### 8.13. PT_MV_LONG

PT_MV_LONG are arrays ("multiple values") of integers. OCPF defines PT_MV_LONG property values as INTEGER property values separated by commas and enclosed within braces.

{ INTEGER, INTEGER, INTEGER }

At least one INTEGER property value is required to create a valid PT_MV_LONG property. If two or more INTEGER property values are set, then they must be separated with comma.

Also note that PT_MV_LONG are very similar to PT_BINARY in their syntax. The main difference lies in the representation of UINT8 and INTEGER values.

{ 1, 2, 3 }
{ L0x1, 0x123456, 42 }

## 9. Comments

OCPF files can contain comments embedded in normal C-style comment markers. That is, a comment starts with a combination of / followed by *, and ends with combination of * followed by /.

Anything contained with in comment markers is ignored by the OCPF tools, and is only for the convenience of human readers.

/* This is a comment */

## 10. OCPF and openchangeclient

OCPF support has been added to the openchangeclient utility. It now has the ability to parse and process OCPF files. Two different options are supported; you can either check an OCPF files' syntax (–ocpf_syntax) or process the files (–ocpf_sender).

Users can set OCPF files using –ocpf-file=filename. Note that you can specify –ocpf-file multiple times if you have split the OCPF contents into different files. However the whole OCPF files you specify must only represent a single message.

Sample OCPF files are provided in the distribution (libocpf/examples), and can also be browsed from the Examples section of this documentation:

- sample_appointment.ocpf
- sample_task.ocpf

## 10.1 ocpf_syntax

Process specified OCPF files, display syntax errors if detected and dump OCPF context content on standard output.

openchangeclient --ocpf-syntax \
--ocpf-file=libocpf/examples/sample_appointment.ocpf

## 10.2. ocpf_sender

Process specified OCPF files and create/send a message using OCPF context contents.

openchangeclient --ocpf_sender \
--ocpf-file=libocpf/examples/sample_appointment.ocpf

## 10.3 ocpf_dump

Process specified MAPI message and generates the corresponding OCPF file on the filesystem.

openchangeclient --fetch-items=Appointment
MAILBOX (1 messages)
|== test ==| : AA13000000000001/20C140000000003
Location: paris
Start time : Sat Mar 29 09:00:00 2008 CET
End time : Sat Mar 29 09:30:00 2008 CET
Timezone: (GMT+01:00) Brussels, Copenhagen, Madrid, Paris
Private: False
Status: Completed
fetchitems : MAPI_E_SUCCESS (0x0)
openchangeclient --ocpf-dump=AA13000000000001/20C140000000003
OCPF output file: 20c140000000003.ocpf
OCPF Dump : MAPI_E_SUCCESS (0x0)

| This content is licensed under the Creative Commons Attribution ShareAlike License v. 3.0: http://creativecommons.org/licenses/by-sa/3.0/