4.2 Initiating a Session as Secondary Partner

In this example, the first partner is on Machine_1 with contact identifier (CID) (474cf518-d7ae-451f-a31f-caad29fa5e9f), 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 secondary partner, and the second partner assumes the role of the primary partner. This example assumes that the secondary partner does not have an existing session with the primary partner, as there is only one established session between any two partners.

Because this is a new session, the secondary partner will create a new session object. However, the secondary partner will not generate a session GUID, but will obtain the session GUID from the primary partner BuildContextW call. The session object is keyed to the primary partner's name object and is maintained in a list for the secondary partner to ensure that there is only one session established with the primary partner.

To begin a session, the secondary partner obtains an RPC binding handle (0x00227b88) from the primary partner's name object, as described in section 1.3.2. Because it is against protocol for the secondary partner to send the first BuildContextW call, the secondary partner uses the binding handle to send a PokeW call to the primary partner. In the Poke call, the secondary partner passes its NetBIOS machine name (pszHostName) and contact identifier (CID) (pszUuidString) and the primary partner contact identifier (CID) (pszCalleeUuid). In the BindInfo (rguchBlob), the secondary partner indicates that it supports PROT_IP_TCP (bit 0) and PROT_LRPC (bit 5). See section 2.2.4.

Field

Value description

hRPC

RPC_BINDING_HANDLE=0x00227b88

sRank

SRANK_SECONDARY

pwszCalleeUuid

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

pwszHostName

L"Machine_1"

pwszUuidString

L"474cf518-d7ae-451f-a31f-caad29fa5e9f"

dwcbSizeOfBlob

dwcbSizeOfBlob: 8

rguchBlob

dwcbThisStruct : 8

PROT_IP_TCP | PROT_LRPC

When the primary partner receives the Poke call from the secondary partner, the primary partner will attempt to locate an existing session object associated with the secondary partner. If an existing session object is found, the primary 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 primary partner will create a new session object and identify it with a newly generated session GUID. The session object is keyed to the secondary partner's name object and is maintained in a list for the primary partner to ensure that there is only one session established with the secondary partner. At this point, the primary partner replies S_OK to the Poke call from the secondary partner, and assumes the role of the primary partner.

As in the first example (see section 4.1), the primary partner obtains an RPC binding handle (0x004dae28) from the secondary partner's name object (see section 1.3.2) to begin a session. 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 / and BuildContextW method calls, that it supports version 1 of the level-two protocol and version 5 of the level-three protocol. 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's PCONTEXT_HANDLE when the session is accepted.

Field

Value description

hRPC

RPC_BINDING_HANDLE=0x004dae28

sRank

SRANK_PRIMARY

BindVersionSet

dwMinLevelOne : 1

dwMaxLevelOne : 2

dwMinLevelTwo : 1

dwMaxLevelTwo : 1

dwMinLevelThree : 1

dwMaxLevelThree : 5

pwszCalleeUuid

L"474cf518-d7ae-451f-a31f-caad29fa5e9f"

pwszHostName

L"Machine_2"

pwszUuidString

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

pwszGuidIn

L"79135638-e1c2-4fb5-9a47-6951d28e4d9c"

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 will locate the existing session object associated with the primary partner, and will copy in the session GUID passed to it from the primary partner.

Because the primary partner has specified that it supports both the Poke / BuildContext and PokeW / and BuildContextW method calls (dwMaxLevelOne = 2), the secondary partner sends 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 contact identifier (CID) (pwszCalleeUuid). The secondary partner also passes in the primary partner's session GUID (pwszGuidIn) from the initial call. The secondary partner also passes a pointer to a PCONTEXT_HANDLE, which will be filled when the primary partner accepts the session.

Field

Value description

hRPC

RPC_BINDING_HANDLE=0x00227b88

sRank

SRANK_SECONDARY

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"474cf518-d7ae-451f-a31f-caad29fa5e9f"

pwszGuidIn

L"79135638-e1c2-4fb5-9a47-6951d28e4d9c"

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 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 (0x0012af48) to the RPC context handle associated with its session object via the PPCONTEXT_HANDLE, and replies 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"79135638-e1c2-4fb5-9a47-6951d28e4d9c"

pBoundVersionSet [in_out]

dwLevelOneAccepted : 2

dwLevelTwoAccepted : 1

dwLevelThreeAccepted : 5

ppHandle [out]

*PPCONTEXT_HANDLE=0x0012af48

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 (0x00bf90e0) to the RPC context handle associated with its session object via the PPCONTEXT_HANDLE and 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"79135638-e1c2-4fb5-9a47-6951d28e4d9c"

pBoundVersionSet [in_out]

dwLevelOneAccepted : 2

dwLevelTwoAccepted : 1

dwLevelThreeAccepted : 5

ppHandle [out]

*PPCONTEXT_HANDLE=0x005f90e0

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.