Every object has a set of required properties and a set of optional properties. Depending on the object, the service provider supplying the implementation, and the property, a MAPI client can have read/write or read-only access to a property in either set. A required read/write property is a property that must exist on an object before it can be successfully saved with the IMAPIProp::SaveChanges method. A required read-only property is a property that always exists on an object and is therefore always available by calling either IMAPIProp::GetProps or IMAPIProp::OpenProperty. Read-only properties are typically computed by the service provider supplying the object implementation.
In contrast, MAPI clients cannot expect optional properties to be available or set to valid values. When a MAPI client or service provider calls GetProps, asking for an unavailable property, it succeeds with the warning MAPI_W_ERRORS_RETURNED. However, a call to the MAPI method IMAPIProp::OpenProperty fails with the error MAPI_E_NOT_FOUND. MAPI clients and service providers must verify that a requested property is returned before attempting to use it.
When an optional property is included as one of the columns in a table, some of the rows might have valid values for the column while others might not. Whether or not a valid value exists for a column depends on whether or not the object providing the information for the row sets the property. Depending on the implementation of the object, a non-existent property can be represented in the table as PR_NULL or an arbitrary value. Users of tables must be careful to differentiate between properties that are nonexistent and have meaningless values and properties that do exist and have valid values.
To determine exactly which properties are currently set for an object, MAPI clients and service providers can call IMAPIProp::GetPropList. GetPropList lets a caller find out what is available before an attempt to open a potentially nonexistent property is made. Because there is no standard set of properties that all objects of a specific type support, it is impossible to guess whether or not an object supports a particular property. Calling GetPropList eliminates the guesswork.