4 Protocol Examples
This section illustrates the call sequence of obtaining the address book hierarchy table at the NSPI layer. It further illustrates how a messaging client can use this table to retrieve properties of the address objects using NspiQueryRows.
It is assumed that the messaging client has established an RPC connection to the NSPI server.
Note Only parts of the details of client request parameters and server response parameters are documented, to show only the relevant information.
Figure 2: Example NSPI session message sequence
Client initiates a session to the NSPI server by calling NspiBind. Messaging clients send the following values to the server.
Note Not all parameters are shown, only relevant information.
dwFlags 0x00000000unsigned long pStat SortType 0x00000000 unsigned long ContainerID 0x00000000 unsigned long CurrentRec 0x00000000 unsigned long Delta 0x00000000 long NumPos 0x00000000 unsigned long TotalRecs 0x00000000 unsigned long CodePage 0x000004e4 unsigned long TemplateLocale 0x00000409 unsigned long SortLocale 0x00000409 unsigned long pServerGuid pointer to an array of 16 unsigned char to be returned by the server
Server responds to NspiBind call with return code Success and a valid server GUID.
Typical parameters look like this.
pServerGuid [0x0]0xab 0xbc 0x8b 0x86 0x79 0x33 0xc4 0x48 0xa1 0xef [0xa]0x1b 0x53 0xe6 0x3b 0xdc 0x46 contextHandle <a token>
Client requests the address book hierarchy table from the server by calling NspiGetSpecialTable with dwFlags typically set to the NspiUnicodeStrings bit flag. More importantly, the client does not set the NspiAddressCreationTemplates flag.
Typical parameters look like this.
dwFlags0x00000004unsigned long pStat SortType 0x00000000 unsigned long ContainerID 0x00000000 unsigned long CurrentRec 0x00000000 unsigned long Delta 0x00000000 long NumPos 0x00000000 unsigned long TotalRecs 0x00000000 unsigned long CodePage 0x000004e4 unsigned long TemplateLocale 0x00000409 unsigned long SortLocale 0x00000409 unsigned long ppRows <memory location that holds _PropertyRowSet_r** returned by the server>
Server responds to the NspiGetSpecialTable call with return code Success, and the rows of the address book hierarchy table typically have the following columns set: PidTagEntryId, PidTagContainerFlags, PidTagDepth, PidTagAddressBookContainerId, PidTagDisplayName, and PidTagAddressBookIsMaster as described in [MS-OXOABK]. In this example, the server did not return the optional PidTagAddressBookParentEntryId.
Note Not all return parameters are shown, only relevant information.
A typical table looks like this.
ppRows_PropertyRowSet_r * * { cRows=0x00000007 aRow=<a pointer to an array of rows> }
In this example, the server has returned a total of 0x7 rows denoted as [0x0]...[0x6], and each row typically looks like this.
aRow[0x0] ... [0x6]_PropertyRow_r * { Reserved=0x00000000 cValues=0x00000006 lpProps=<a pointer to an array of columns> }
In this example, the server has returned a column set of six properties, and each column looks like this.
[0x0]_PropertyValue_r { ulPropTag=PidTagEntryId dwAlignPad=0x00000000 Value={...} } [0x1]_PropertyValue_r { ulPropTag=PidTagContainerFlags dwAlignPad=0x00000000 Value={...} } [0x2]_PropertyValue_r { ulPropTag=PidTagDepth dwAlignPad=0x00000000 Value={...} } [0x3]_PropertyValue_r { ulPropTag=PidTagAddressBookContainerId dwAlignPad=0x00000000 Value={...} } [0x4]_PropertyValue_r { ulPropTag=PidTagDisplayName dwAlignPad=0x00000000 Value={...} } [0x5]_PropertyValue_r { ulPropTag=PidTagAddressBookIsMaster dwAlignPad=0x00000000 Value={...} }
Note Client can invoke additional NSPI calls to access other information from the server before calling NspiUnbind.
Messaging clients call NspiQueryRows to retrieve various properties of Address Book objects. The following example illustrates the client requesting the server a total of two rows containing specific properties PidTagEntryId, PidTagDisplayName, PidTagSmtpAddress, and PidTagTitle. Also, the client is requesting the server to use the pStat structure for table information by setting lpETable NULL and setting relevant values in the pStat structure. It typically looks like this.<15>
Note Not all return parameters are shown, only relevant information.
pStat SortType 0x00000000 unsigned long ContainerID 0x00000000 unsigned long CurrentRec 0x00000000 unsigned long Delta 0x00000000 long NumPos 0x00000000 unsigned long TotalRecs 0xffffffff unsigned long CodePage 0x000004e4 unsigned long TemplateLocale0x00000409 unsigned long SortLocale0x00000409 unsigned long dwETableCount00x00000000 unsigned long lpETable0x00000000 unsigned long * Count0x00000002 unsigned long Flags0x00000000 unsigned long pPropTags_PropertyTagArray_r * { cValues=0x00000004 aulPropTag=<a pointer to an array of properties> } aulPropTag<array of 4 PropTags> [0x0]PidTagEntryIdunsigned long [0x1]PidTagDisplayNameunsigned long [0x2]PidTagSmtpAddressunsigned long [0x3]PidTagTitleunsigned long
The server responds to the NspiQueryRows call with return code Success and a row set.
Note Not all parameters are shown, only relevant information.
Typical return parameters are as follows.
dwFlags 0x00000000unsigned long pStat SortType 0x00000000 unsigned long ContainerID 0x00000000 unsigned long CurrentRec 0x00001928 unsigned long Delta 0x00000000 long NumPos 0x00000002 unsigned long TotalRecs 0x00000016 unsigned long CodePage 0x000004e4 unsigned long TemplateLocale 0x00000409 unsigned long SortLocale 0x00000409 unsigned long dwETableCount 0x00000000 unsigned long lpETable 0x00000000 unsigned long * Count 0x00000002 unsigned long pPropTags_PropertyRowSet_r * * { cRows=0x00000002 aRow=<a pointer to an array of rows> }
In this example, the server has returned a total of 0x2 rows denoted as [0x0]...[0x1] equal to the number of rows requested by the client. Each row typically looks like this.
aRow[0x0] ... [0x1]_PropertyRow_r * { Reserved=0x00000000 cValues=0x00000004 lpProps=<a pointer to an array of columns> }
In this example, the server has returned a column set of four properties equal to the number of properties requested by the client. Each column looks like this.
[0x0]_PropertyValue_r { ulPropTag= PidTagEntryId dwAlignPad=0x00000000 Value={...} } [0x1]_PropertyValue_r { ulPropTag= PidTagDisplayName dwAlignPad=0x00000000 Value={...} } [0x2]_PropertyValue_r { ulPropTag= PidTagSmtpAddress dwAlignPad=0x00000000 Value={...} } [0x3]_PropertyValue_r { ulPropTag= PidTagTitle dwAlignPad=0x00000000 Value={...} }
The client terminates the connection by calling NspiUnbind with a token that the server returned in response to the NspiBind call.
contextHandleNSPI_HANDLE * <a token> dwFlags0x00000000unsigned long
Server responds with return code 0x00000001 and destroys the token that the client passed.