Named Properties¶
Named properties allow applications to define custom properties beyond the standard MAPI property set. They are identified by a GUID (property set) and either a numeric ID or a string name.
Understanding Named Properties¶
Standard MAPI properties use fixed property IDs (e.g., 0x0037 for Subject). Named properties extend this by mapping custom identifiers to property IDs in the range 0x8000 to 0xFFFE.
Property Identification¶
Named properties can be identified in two ways:
- MNID_ID: By a numeric ID within a property set GUID
- MNID_STRING: By a string name within a property set GUID
Accessing the Named Property Map¶
pst, _ := outlookpst.Open("archive.pst")
defer pst.Close()
// Get the named property map
npm, err := pst.NamedPropertyMap()
if err != nil {
log.Fatal(err)
}
fmt.Printf("Named properties: %d\n", npm.Count())
Looking Up Named Properties¶
By Numeric ID¶
// Look up a property by GUID and numeric ID
np, found := npm.Lookup(util.PSETID_Common, 0x8501)
if found {
fmt.Printf("Property: %s\n", np.String())
fmt.Printf("Mapped to: 0x%04X\n", np.PropID)
}
By String Name¶
// Look up a property by GUID and string name
np, found := npm.LookupByName(util.PS_PUBLIC_STRINGS, "Keywords")
if found {
fmt.Printf("Property: %s\n", np.String())
}
By Property ID¶
// Look up by the mapped property ID
np, found := npm.LookupByPropID(0x8005)
if found {
fmt.Printf("GUID: %s\n", np.GUID.String())
if np.Kind == ltp.MNID_ID {
fmt.Printf("ID: 0x%04X\n", np.ID)
} else {
fmt.Printf("Name: %s\n", np.Name)
}
}
Well-Known Property Sets¶
The library includes common property set GUIDs:
| Variable | Description |
|---|---|
util.PS_MAPI |
Standard MAPI properties |
util.PS_PUBLIC_STRINGS |
Public string properties |
util.PS_INTERNET_HEADERS |
Internet mail headers |
util.PSETID_Common |
Common message properties |
util.PSETID_Address |
Address book properties |
util.PSETID_Appointment |
Calendar/appointment properties |
util.PSETID_Meeting |
Meeting request properties |
util.PSETID_Task |
Task properties |
util.PSETID_Note |
Note properties |
Reading Named Property Values¶
Once you have the mapped property ID, use it with the PropertyBag:
// Get the mapped property ID
propID, found := npm.GetPropID(util.PSETID_Common, 0x8501)
if !found {
log.Fatal("Property not found")
}
// Use it to read the property value
msg, _ := folder.Messages().Next()
bag := msg.PropertyBag()
if bag.Exists(propID) {
value, _ := bag.GetString(propID)
fmt.Printf("Value: %s\n", value)
}
Listing All Named Properties¶
npm, _ := pst.NamedPropertyMap()
for _, np := range npm.Entries() {
if np.Kind == ltp.MNID_ID {
fmt.Printf("{%s}:0x%04X -> 0x%04X\n",
np.GUID.String(), np.ID, np.PropID)
} else {
fmt.Printf("{%s}:%q -> 0x%04X\n",
np.GUID.String(), np.Name, np.PropID)
}
}
Common Named Properties¶
Some frequently used named properties:
| Property Set | ID/Name | Description |
|---|---|---|
| PSETID_Common | 0x8501 | Reminder set flag |
| PSETID_Common | 0x8502 | Reminder time |
| PSETID_Common | 0x8503 | Reminder delta |
| PSETID_Appointment | 0x8205 | Appointment duration |
| PSETID_Appointment | 0x8208 | Location |
| PSETID_Task | 0x8101 | Task status |
| PS_PUBLIC_STRINGS | "Keywords" | Categories |
Example: Reading Categories¶
func getCategories(pst *outlookpst.PST, msg *outlookpst.Message) ([]string, error) {
npm, err := pst.NamedPropertyMap()
if err != nil {
return nil, err
}
// Keywords/Categories is stored as a multi-value string
propID, found := npm.GetPropIDByName(util.PS_PUBLIC_STRINGS, "Keywords")
if !found {
return nil, nil
}
bag := msg.PropertyBag()
if !bag.Exists(propID) {
return nil, nil
}
return bag.GetStringSlice(propID)
}
Specification Reference¶
Named properties are defined in:
- [MS-PST] Section 2.4.7 - Name-to-ID Map
- [MS-OXPROPS] - Property definitions