4.1 Initiating a Session as Primary Partner

In this example, the first partner is on Machine_1 with contact identifier (CID) b51996ef-c434-4f79-a288-56efd302fc8e, and the second partner is on Machine_2 with contact identifier (CID) a3afb37b-f64a-4e6c-9017-f6a96ba6f166. Therefore, the first partner assumes the role of the primary partner, and the second partner assumes the role of the secondary partner.

In this example, both partners support the PokeW and BuildContextW method calls. This example assumes that the primary partner does not have an existing session with the secondary partner, because only one session is allowed between any two partners.

Because this is a new session, the primary partner will create a new object with a newly generated session GUID. The session object is keyed to the session secondary partner name object and is maintained in a list to ensure that there is only one session established with the secondary partner.

To begin a session, the primary partner obtains an RPC binding handle (0x004377b0) from the secondary partner name object, as described in section 1.3.2. The primary partner uses the binding handle to send a BuildContextW call to the secondary partner using SRANK_PRIMARY. In the BuildContextW call, the primary partner passes its NetBIOS machine name (pwszHostName) and contact identifier (CID) (pwszUuidString), and the secondary partner's contact identifier (CID) (pwszCalleeUuid). The primary partner also sends the session GUID (pwszGuidIn), which will be returned in pwszGuidOut when the session is accepted. In the BindVersionSet, the primary partner indicates that it supports both the Poke / BuildContext and PokeW / BuildContextW method calls, that it supports version 1 of the level-two protocol and version 5 of the level-three protocol. (In this example, this is version 1 of the protocol described in [MS-CMP], and version 5 of this protocol, which is the current version at the level of Windows XP operating system Service Pack 2 (SP2), Windows Server 2003 operating system with Service Pack 1 (SP1), or Windows Vista operating system.) In the BindInfo (rguchBlob), the primary partner indicates that it supports PROT_IP_TCP (bit 0) and PROT_LRPC (bit 5). See section 2.2.4. The primary partner also passes a pointer to a PCONTEXT_HANDLE, into which it will receive the secondary partner PCONTEXT_HANDLE when the session is accepted.

Field

Value description

hRPC

RPC_BINDING_HANDLE=0x004377b0

sRank

SRANK_PRIMARY

BindVersionSet

dwMinLevelOne : 1

dwMaxLevelOne : 2

dwMinLevelTwo : 1

dwMaxLevelTwo : 1

dwMinLevelThree : 1

dwMaxLevelThree : 5

pwszCalleeUuid

L"a3afb37b-f64a-4e6c-9017-f6a96ba6f166"

pwszHostName

L"Machine_1"

pwszUuidString

L"b51996ef-c434-4f79-a288-56efd302fc8e"

pwszGuidIn

L"a5acacb4-b766-4074-b45d-ade720d1d8e8"

pwszGuidOut [in_out]

L"00000000-0000-0000-0000-000000000000"

pBoundVersionSet [in_out]

dwLevelOneAccepted : 0

dwLevelTwoAccepted : 0

dwLevelThreeAccepted : 0

dwcbSizeOfBlob

dwcbSizeOfBlob: 8

rguchBlob

dwcbThisStruct : 8

PROT_IP_TCP | PROT_LRPC

ppHandle [out]

*PPCONTEXT_HANDLE=0x00000000

When the secondary partner receives the BuildContextW call from the primary partner, the secondary partner attempts to locate an existing session object associated with the primary partner. If an existing session object is found, the secondary partner returns E_CM_SERVER_NOT_READY (0x80000123), which will occur if a previous session has not been completely torn down before a new session is begun.

If no existing session is found, the secondary partner will create a new session object with session GUID passed to it from the primary partner. The session object is keyed to the primary partner name object and is maintained in a list maintained by the secondary partner to ensure that one session is established with the primary partner.

To complete the session, the secondary partner obtains an RPC binding handle (0x001e7bd0) from the primary partner's name object, as described in section 1.3.2. The secondary partner uses the binding handle to send a BuildContextW message call to the primary partner using SRANK_SECONDARY. In the BuildContextW call to the primary partner, the secondary partner passes its NetBIOS machine name (pwszHostName) and contact identifier (CID) (pwszUuidString) and the primary partner's contact identifier (CID) (pwszCalleeUuid). The secondary partner also passes in the primary partner's session GUID (pwszGuidIn) from the initial call and a pointer to a PCONTEXT_HANDLE, which will be filled when the primary partner accepts the session.

Field

Value description

hRPC

RPC_BINDING_HANDLE=0x001e7bd0

sRank

SRANK_SECONDARY

BindVersionSet

dwMinLevelOne : 1

dwMaxLevelOne : 2

dwMinLevelTwo : 1

dwMaxLevelTwo : 1

dwMinLevelThree : 1

dwMaxLevelThree : 5

pwszCalleeUuid

L"b51996ef-c434-4f79-a288-56efd302fc8e"

pwszHostName

L"Machine_2"

pwszUuidString

L"a3afb37b-f64a-4e6c-9017-f6a96ba6f166"

pwszGuidIn

L"a5acacb4-b766-4074-b45d-ade720d1d8e8"

pwszGuidOut [in_out]

L"00000000-0000-0000-0000-000000000000"

pBoundVersionSet [in_out]

dwLevelOneAccepted : 0

dwLevelTwoAccepted : 0

dwLevelThreeAccepted : 0

dwcbSizeOfBlob [in_out]

dwcbSizeOfBlob: 8

rguchBlob

dwcbThisStruct : 8

PROT_IP_TCP | PROT_LRPC

ppHandle [out]

*PPCONTEXT_HANDLE=0x00000000

When the BuildContextW call is received by the primary partner, the primary partner fills in the pwszGuidOut with the session GUID from pwszGuidIn, and will fill in the BoundVersionSet with its accepted values. The primary partner will also pass a reference pointer (0x00436e68) to the RPC context handle associated with its session object via the PPCONTEXT_HANDLE, and will reply S_OK. Once the session is established, all future communication from the secondary partner will reference this PCONTEXT_HANDLE.

Field

Value description

pwszGuidOut [in_out]

L"a5acacb4-b766-4074-b45d-ade720d1d8e8"

pBoundVersionSet [in_out]

dwLevelOneAccepted : 2

dwLevelTwoAccepted : 1

dwLevelThreeAccepted : 5

ppHandle [out]

*PPCONTEXT_HANDLE=0x00436e68

When S_OK is returned to the secondary partner on its BuildContextW call, the secondary partner fills in the pszGuidOut with the session GUID from pszGuidIn and sets the accepted values for the BoundVersionSet. The secondary partner will also pass a reference pointer (0x0053b710) to the RPC context handle associated with its session object via the PPCONTEXT_HANDLE and will reply S_OK. Once the session is established, all future communication from the primary partner will need to reference this PCONTEXT_HANDLE.

Field

Value description

pwszGuidOut [in_out]

L"a5acacb4-b766-4074-b45d-ade720d1d8e8"

pBoundVersionSet [in_out]

dwLevelOneAccepted : 2

dwLevelTwoAccepted : 1

dwLevelThreeAccepted : 5

ppHandle [out]

*PPCONTEXT_HANDLE=0x0053b710

At this point, a session has been established between the primary partner and the secondary partner. Either partner is now free to call NegotiateResources and initiate connections.