2536 lines
56 KiB
C++
2536 lines
56 KiB
C++
/*++
|
||
|
||
Copyright (C) Microsoft Corporation, 1991 - 1999
|
||
|
||
Module Name:
|
||
|
||
osfclnt.hxx
|
||
|
||
Abstract:
|
||
|
||
This file contains the client side classes for the OSF connection
|
||
oriented RPC protocol engine.
|
||
|
||
Author:
|
||
|
||
Michael Montague (mikemon) 17-Jul-1990
|
||
|
||
Revision History:
|
||
Mazhar Mohammed (mazharm) 11-08-1996 - Major re-haul to support async
|
||
- Added support for Async RPC, Pipes
|
||
- Changed class structure
|
||
Kamen Moutafov (kamenm) Jan-2000 Support for multiple transfer syntaxes
|
||
Kamen Moutafov (KamenM) Dec 99 - Feb 2000 - Support for cell debugging stuff
|
||
--*/
|
||
|
||
#ifndef __OSFCLNT_HXX__
|
||
#define __OSFCLNT_HXX__
|
||
|
||
enum OSF_CCALL_STATE
|
||
{
|
||
//
|
||
// Need to open the connection and bind, in order to
|
||
// handle the call
|
||
//
|
||
NeedOpenAndBind = 0,
|
||
|
||
//
|
||
// Need to send an alter context on the connection
|
||
// in order to handle this call
|
||
//
|
||
NeedAlterContext,
|
||
|
||
//
|
||
// We sent an alter-context, we are waiting for a reply
|
||
//
|
||
WaitingForAlterContext,
|
||
|
||
//
|
||
// The call is still sending the non pipe data
|
||
// we need to finish sending this before
|
||
// we can move on the the next call.
|
||
//
|
||
SendingFirstBuffer,
|
||
|
||
//
|
||
// The call is now sending pipe data
|
||
//
|
||
SendingMoreData,
|
||
|
||
//
|
||
// The the call is done sending data. It is now waiting for a reply.
|
||
// The reply may be either a response or a callback.
|
||
//
|
||
WaitingForReply,
|
||
|
||
//
|
||
// The call is receiving a callback from the server
|
||
//
|
||
InCallbackRequest,
|
||
|
||
//
|
||
// The call is in the process of sending a reply to a callback
|
||
//
|
||
InCallbackReply,
|
||
|
||
//
|
||
// We move into this state after receiving the first fragment
|
||
//
|
||
Receiving,
|
||
|
||
//
|
||
// Some failure occured. the call is now in an
|
||
// aborted state
|
||
//
|
||
Aborted,
|
||
|
||
//
|
||
// The call is complete
|
||
//
|
||
Complete
|
||
} ;
|
||
|
||
//
|
||
// Maximum retries in light of getting a shutdown
|
||
// or closed in doing a bind or shutdown
|
||
//
|
||
#define MAX_RETRIES 3
|
||
|
||
// 15 min timeout for bind
|
||
#define RPC_C_SERVER_BIND_TIMEOUT 15*60*1000
|
||
|
||
//
|
||
// These values specify the minimum amount of time in milliseconds to wait before
|
||
// deleting an idle connection. The second is the more aggressive. It will be used
|
||
// when we have more than 500 connections in an association
|
||
//
|
||
|
||
const ULONG AGGRESSIVE_TIMEOUT_THRESHOLD = 500;
|
||
|
||
const ULONG CLIENT_DISCONNECT_TIME1 = 10 * 1000;
|
||
const ULONG CLIENT_DISCONNECT_TIME2 = 5 * 1000;
|
||
|
||
#define InqTransCConnection(RpcTransportConnection) \
|
||
((OSF_CCONNECTION *) \
|
||
((char *) RpcTransportConnection - sizeof(OSF_CCONNECTION)))
|
||
|
||
#define TransConnection() ((RPC_TRANSPORT_CONNECTION) \
|
||
((char *) this+sizeof(OSF_CCONNECTION)))
|
||
#define TransResolverHint() ((void *) ((char *) this+sizeof(OSF_CASSOCIATION)))
|
||
|
||
class OSF_CASSOCIATION;
|
||
class OSF_CCONNECTION ;
|
||
class OSF_BINDING ;
|
||
class OSF_CCALL ;
|
||
|
||
extern MUTEX *AssocDictMutex;
|
||
|
||
|
||
class OSF_RECURSIVE_ENTRY
|
||
/*++
|
||
|
||
Class Description:
|
||
|
||
This class is used to describe the entries in the dictionary of
|
||
recursive calls maintained by each binding handle.
|
||
|
||
Fields:
|
||
|
||
Thread - Contains the thread owning this recursive call.
|
||
|
||
RpcInterfaceInformation - Contains information describing the
|
||
interface
|
||
|
||
CCall - Contains the call
|
||
|
||
--*/
|
||
{
|
||
friend class OSF_BINDING_HANDLE;
|
||
private:
|
||
|
||
THREAD_IDENTIFIER Thread;
|
||
PRPC_CLIENT_INTERFACE RpcInterfaceInformation;
|
||
OSF_CCALL * CCall;
|
||
|
||
public:
|
||
|
||
OSF_RECURSIVE_ENTRY (
|
||
IN THREAD_IDENTIFIER Thread,
|
||
IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation,
|
||
IN OSF_CCALL * CCall
|
||
);
|
||
|
||
OSF_CCALL *
|
||
IsThisMyRecursiveCall (
|
||
IN THREAD_IDENTIFIER Thread,
|
||
IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation
|
||
);
|
||
};
|
||
|
||
|
||
inline
|
||
OSF_RECURSIVE_ENTRY::OSF_RECURSIVE_ENTRY (
|
||
IN THREAD_IDENTIFIER Thread,
|
||
IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation,
|
||
IN OSF_CCALL * CCall
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
All we do in this constructor is stash the arguments passed to us
|
||
away in the object.
|
||
|
||
Arguments:
|
||
|
||
Thread - Supplies the thread for which this is the recursive call.
|
||
|
||
RpcInterfaceInformation - Supplies information describing the
|
||
interface
|
||
|
||
CCall - Supplies the recursive call.
|
||
|
||
--*/
|
||
{
|
||
this->Thread = Thread;
|
||
this->RpcInterfaceInformation = RpcInterfaceInformation;
|
||
this->CCall = CCall;
|
||
}
|
||
|
||
|
||
inline OSF_CCALL *
|
||
OSF_RECURSIVE_ENTRY::IsThisMyRecursiveCall (
|
||
IN THREAD_IDENTIFIER Thread,
|
||
IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine determines if this object contains the recursive call
|
||
for the specified thread and interface information.
|
||
|
||
Arguments:
|
||
|
||
Thread - Supplies the thread.
|
||
|
||
RpcInterfaceInformation - Supplies the interface information.
|
||
|
||
Return Value:
|
||
|
||
If this object contains the recursive call corresponding to the
|
||
specified thread and interface information, then the connection is
|
||
returned. Otherwise, zero will be returned.
|
||
|
||
--*/
|
||
{
|
||
return((((Thread == this->Thread)
|
||
&& (RpcInterfaceInformation == this->RpcInterfaceInformation))
|
||
? CCall : 0));
|
||
}
|
||
|
||
NEW_SDICT(OSF_RECURSIVE_ENTRY);
|
||
|
||
|
||
class RPC_TOKEN
|
||
{
|
||
public:
|
||
HANDLE hToken;
|
||
LUID ModifiedId;
|
||
int RefCount;
|
||
int Key;
|
||
|
||
RPC_TOKEN (HANDLE hToken, LUID *pModifiedId)
|
||
{
|
||
this->hToken = hToken;
|
||
RefCount = 1;
|
||
FastCopyLUIDAligned(&ModifiedId, pModifiedId);
|
||
}
|
||
|
||
~RPC_TOKEN ()
|
||
{
|
||
CloseHandle(hToken);
|
||
}
|
||
};
|
||
|
||
|
||
|
||
class OSF_BINDING_HANDLE : public BINDING_HANDLE
|
||
/*++
|
||
|
||
Class Description:
|
||
|
||
Client applications use instances (referenced via an RPC_BINDING_HANDLE)
|
||
of this class to make remote procedure calls.
|
||
|
||
Fields:
|
||
|
||
Association - Contains a pointer to the association used by this
|
||
binding handle. The association can allocate connection for
|
||
making remote procedure calls. Before the first remote procedure
|
||
call is made using this binding handle, the Association will
|
||
be zero. When the first remote procedure call is made, an
|
||
assocation will be found or created for use by this binding handle.
|
||
|
||
DceBinding - Before the first remote procedure call for this binding
|
||
handle, this will contain the DCE binding information necessary
|
||
to create or find an association to be used by this binding handle.
|
||
After we have an association, this field will be zero.
|
||
|
||
TransportInterface - This field is the same as DceBinding, except that
|
||
it points to a rpc client info data structure used for describing
|
||
a loadable transport.
|
||
|
||
RecursiveCalls - This is a dictionary of recursive calls indexed
|
||
by thread identifier and rpc interface information.
|
||
|
||
BindingMutex - The binding handle can be used by more than one thread
|
||
at a time. Hence, we need to serialize access to the object;
|
||
we use this mutex for that.
|
||
|
||
ReferenceCount - We count the number of active connections and the
|
||
application RPC_BINDING_HANDLE which point at this object. This
|
||
is so that we know when to free it.
|
||
|
||
--*/
|
||
{
|
||
friend class OSF_CCALL;
|
||
|
||
private:
|
||
|
||
OSF_CASSOCIATION * Association;
|
||
DCE_BINDING * DceBinding;
|
||
TRANS_INFO *TransInfo ;
|
||
OSF_RECURSIVE_ENTRY_DICT RecursiveCalls;
|
||
UINT ReferenceCount;
|
||
RPC_TOKEN *pToken;
|
||
|
||
public:
|
||
// set for Remote named pipes only
|
||
BOOL fNamedPipe;
|
||
BOOL TransAuthInitialized;
|
||
BOOL fDynamicEndpoint;
|
||
|
||
OSF_BINDING_HANDLE (
|
||
IN OUT RPC_STATUS * RpcStatus
|
||
);
|
||
|
||
~OSF_BINDING_HANDLE (
|
||
);
|
||
|
||
virtual RPC_STATUS
|
||
NegotiateTransferSyntax (
|
||
IN OUT PRPC_MESSAGE Message
|
||
);
|
||
|
||
virtual RPC_STATUS
|
||
GetBuffer (
|
||
IN OUT PRPC_MESSAGE Message,
|
||
IN UUID *ObjectUuid
|
||
);
|
||
|
||
virtual RPC_STATUS
|
||
BindingCopy (
|
||
OUT BINDING_HANDLE * * DestinationBinding,
|
||
IN UINT MaintainContext
|
||
);
|
||
|
||
virtual RPC_STATUS
|
||
BindingFree (
|
||
);
|
||
|
||
virtual RPC_STATUS
|
||
PrepareBindingHandle (
|
||
IN TRANS_INFO * TransportInterface,
|
||
IN DCE_BINDING * DceBinding
|
||
);
|
||
|
||
virtual RPC_STATUS
|
||
ToStringBinding (
|
||
OUT RPC_CHAR * * StringBinding
|
||
);
|
||
|
||
virtual RPC_STATUS
|
||
ResolveBinding (
|
||
IN RPC_CLIENT_INTERFACE * RpcClientInterface
|
||
);
|
||
|
||
virtual RPC_STATUS
|
||
BindingReset (
|
||
);
|
||
|
||
virtual RPC_STATUS
|
||
InquireTransportType(
|
||
OUT UINT *Type
|
||
)
|
||
{ *Type = TRANSPORT_TYPE_CN; return(RPC_S_OK); }
|
||
|
||
virtual ULONG
|
||
MapAuthenticationLevel (
|
||
IN ULONG AuthenticationLevel
|
||
);
|
||
|
||
virtual void
|
||
AddReference (
|
||
)
|
||
{
|
||
BindingMutex.Request();
|
||
ReferenceCount++;
|
||
BindingMutex.Clear();
|
||
}
|
||
|
||
RPC_STATUS
|
||
AllocateCCall (
|
||
OUT OSF_CCALL * * CCall,
|
||
IN PRPC_MESSAGE Message,
|
||
OUT BOOL *Retry
|
||
);
|
||
|
||
RPC_STATUS
|
||
AddRecursiveEntry (
|
||
IN OSF_CCALL * CCall,
|
||
IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation
|
||
);
|
||
|
||
void
|
||
RemoveRecursiveCall (
|
||
IN OSF_CCALL * CCall
|
||
);
|
||
|
||
OSF_CASSOCIATION *
|
||
TheAssociation (
|
||
) {return(Association);}
|
||
|
||
OSF_CASSOCIATION *
|
||
FindOrCreateAssociation (
|
||
IN DCE_BINDING * DceBinding,
|
||
IN TRANS_INFO * TransInfo,
|
||
IN RPC_CLIENT_INTERFACE *InterfaceInfo
|
||
);
|
||
|
||
RPC_STATUS
|
||
AcquireCredentialsForTransport (
|
||
);
|
||
|
||
BOOL
|
||
SwapToken (
|
||
HANDLE *OldToken
|
||
);
|
||
|
||
void Unbind ();
|
||
|
||
virtual RPC_STATUS
|
||
SetTransportOption( unsigned long option,
|
||
ULONG_PTR optionValue );
|
||
|
||
virtual RPC_STATUS
|
||
InqTransportOption( unsigned long option,
|
||
ULONG_PTR * pOptionValue );
|
||
};
|
||
|
||
const unsigned int BindingListPresent = 1;
|
||
|
||
class OSF_CCONNECTION ;
|
||
enum CANCEL_STATE {
|
||
CANCEL_NOTREGISTERED = 0,
|
||
CANCEL_INFINITE,
|
||
CANCEL_NOTINFINITE
|
||
};
|
||
|
||
class OSF_CCALL : public CCALL
|
||
/*++
|
||
|
||
Class Description:
|
||
This class encapsulates an RPC call.
|
||
|
||
Fields:
|
||
|
||
PresentationContext - This field is only valid when there is a remote
|
||
procedure call in progress on this connection; it contains the
|
||
presentation context for the call.
|
||
|
||
DispatchTableCallback - This field is only valid when there is a remote
|
||
procedure call in progress on this connection; it contains the
|
||
dispatch table to use for callbacks.
|
||
|
||
Association - Contains a pointer to the association which owns this
|
||
connection.
|
||
|
||
TokenLength - Contains the maximum size of a token for the security
|
||
package being used by this connection; we need to keep track of
|
||
this for the third leg authentication case.
|
||
|
||
--*/
|
||
{
|
||
|
||
//
|
||
// This class will only access the AssociationKey member.
|
||
//
|
||
|
||
friend class OSF_CASSOCIATION;
|
||
friend class OSF_CCONNECTION;
|
||
friend class OSF_BINDING_HANDLE;
|
||
|
||
public:
|
||
OSF_CCALL_STATE CurrentState ;
|
||
|
||
private:
|
||
OSF_CCONNECTION *Connection ;
|
||
OSF_BINDING_HANDLE *BindingHandle;
|
||
#ifdef DEBUGRPC
|
||
int CallbackLevel;
|
||
#endif
|
||
|
||
// don't access the struct members directly - only through
|
||
// the access functions - this will ensure that the
|
||
// contents of the struct is properly checked. Async first
|
||
// calls on new connection have both elements valid if there
|
||
// are no preferences. Since this is the only case where
|
||
// this condition is true, we can use it as a flag.
|
||
struct
|
||
{
|
||
// NULL if no binding is selected
|
||
OSF_BINDING *SelectedBinding;
|
||
|
||
// this is the list of differning only by transfer syntax
|
||
// bindings this call can use. It can have one or more
|
||
// elements.
|
||
// This may be NULL if the call doesn't need a list
|
||
OSF_BINDING *AvailableBindingsList;
|
||
} Bindings;
|
||
|
||
void *CurrentBuffer ;
|
||
BOOL fDataLengthNegotiated;
|
||
int CurrentOffset ;
|
||
ULONG CurrentBufferLength ;
|
||
ULONG CallId;
|
||
UINT RcvBufferLength ;
|
||
BOOL FirstSend ;
|
||
PRPC_DISPATCH_TABLE DispatchTableCallback;
|
||
UINT MaximumFragmentLength;
|
||
|
||
// starts from 0, and set to non-zero if security is used after
|
||
// negotiating the bind
|
||
UINT MaxSecuritySize ;
|
||
UINT MaxDataLength;
|
||
int ProcNum ;
|
||
unsigned char *ReservedForSecurity ;
|
||
UINT SecBufferLength;
|
||
|
||
// When the call is created, set to 0, because we don't know whether
|
||
// there is object UUID or not. During GetBuffer we will know, and then
|
||
// we will set it properly. Starting from 0 allows the bind and GetBuffer
|
||
// threads (if different) to check and to synchronize the updating of the
|
||
// max fragment size, since it depends both on the object UUID and
|
||
// the security negotiation
|
||
UINT HeaderSize;
|
||
UINT AdditionalSpaceForSecurity;
|
||
ULONG SavedHeaderSize;
|
||
void * SavedHeader;
|
||
void * LastBuffer ;
|
||
EVENT SyncEvent ;
|
||
UINT ActualBufferLength;
|
||
UINT NeededLength;
|
||
void *CallSendContext;
|
||
INTERLOCKED_INTEGER fAdvanceCallCount;
|
||
BOOL fPeerChoked;
|
||
|
||
// Extended Error Info stuff
|
||
// used in async calls only to hold
|
||
// information b/n call failure and
|
||
// RpcAsyncCompleteCall
|
||
ExtendedErrorInfo *EEInfo;
|
||
|
||
BOOL fDoFlowControl;
|
||
public:
|
||
BOOL fLastSendComplete;
|
||
MUTEX CallMutex ;
|
||
int RecursiveCallsKey;
|
||
|
||
//
|
||
// Indicates the call stack. Whenever a request message is sent or
|
||
// received, the stack is incremented. Likewise, whenever a response
|
||
// message is sent or received, the stack is decremented.
|
||
//
|
||
int CallStack;
|
||
BOOL fCallCancelled;
|
||
CANCEL_STATE CancelState;
|
||
|
||
private:
|
||
QUEUE BufferQueue ;
|
||
BOOL InReply;
|
||
BOOL fChoked;
|
||
|
||
OSF_CCALL (
|
||
RPC_STATUS * pStatus
|
||
);
|
||
|
||
public:
|
||
|
||
virtual~OSF_CCALL (
|
||
);
|
||
|
||
virtual RPC_STATUS
|
||
NegotiateTransferSyntax (
|
||
IN OUT PRPC_MESSAGE Message
|
||
);
|
||
|
||
virtual RPC_STATUS
|
||
GetBuffer (
|
||
IN OUT PRPC_MESSAGE Message,
|
||
IN UUID *ObjectUuid = 0
|
||
);
|
||
|
||
RPC_STATUS
|
||
GetBufferWithoutCleanup (
|
||
IN OUT PRPC_MESSAGE Message,
|
||
IN UUID *ObjectUuid
|
||
);
|
||
|
||
virtual RPC_STATUS
|
||
SendReceive (
|
||
IN OUT PRPC_MESSAGE Message
|
||
);
|
||
|
||
RPC_STATUS
|
||
SendReceiveHelper (
|
||
IN OUT PRPC_MESSAGE Message,
|
||
OUT BOOL *fRetry
|
||
);
|
||
|
||
virtual RPC_STATUS
|
||
Send (
|
||
IN PRPC_MESSAGE Message
|
||
);
|
||
|
||
virtual RPC_STATUS
|
||
Receive (
|
||
IN PRPC_MESSAGE Message,
|
||
IN UINT Size
|
||
);
|
||
|
||
virtual void
|
||
FreeBuffer (
|
||
IN PRPC_MESSAGE Message
|
||
);
|
||
|
||
virtual void
|
||
FreePipeBuffer (
|
||
IN PRPC_MESSAGE Message
|
||
);
|
||
|
||
virtual RPC_STATUS
|
||
ReallocPipeBuffer (
|
||
IN PRPC_MESSAGE Message,
|
||
IN UINT NewSize
|
||
);
|
||
|
||
virtual RPC_STATUS
|
||
AsyncSend (
|
||
IN OUT PRPC_MESSAGE Message
|
||
);
|
||
|
||
virtual RPC_STATUS
|
||
AsyncReceive (
|
||
IN OUT PRPC_MESSAGE Message,
|
||
IN UINT Size
|
||
);
|
||
|
||
virtual void
|
||
ProcessSendComplete (
|
||
IN RPC_STATUS EventStatus,
|
||
IN BUFFER Buffer
|
||
);
|
||
|
||
virtual RPC_STATUS
|
||
CancelAsyncCall (
|
||
IN BOOL fAbort
|
||
);
|
||
|
||
virtual void
|
||
FreeObject (
|
||
);
|
||
|
||
RPC_STATUS
|
||
SendHelper (
|
||
IN PRPC_MESSAGE Message,
|
||
OUT BOOL *fFirstSend
|
||
);
|
||
|
||
RPC_STATUS
|
||
SendData (
|
||
IN BUFFER Buffer
|
||
);
|
||
|
||
RPC_STATUS
|
||
SendMoreData (
|
||
IN BUFFER Buffer
|
||
);
|
||
|
||
RPC_STATUS
|
||
ActuallyAllocateBuffer (
|
||
OUT void * * Buffer,
|
||
IN UINT BufferLength
|
||
);
|
||
|
||
void
|
||
ActuallyFreeBuffer (
|
||
IN void * Buffer
|
||
);
|
||
|
||
//
|
||
// Actually perform the buffer allocation.
|
||
//
|
||
RPC_STATUS
|
||
GetBufferDo (
|
||
IN UINT culRequiredLength,
|
||
OUT void * * ppBuffer,
|
||
IN int fDataValid = 0,
|
||
IN int DataLength = 0
|
||
);
|
||
|
||
void
|
||
FreeBufferDo (
|
||
IN void *Buffer
|
||
);
|
||
|
||
RPC_STATUS
|
||
ActivateCall (
|
||
IN OSF_BINDING_HANDLE *BindingHandle,
|
||
IN OSF_BINDING *Binding,
|
||
IN OSF_BINDING *AvailableBindingsList,
|
||
IN ULONG CallIdToUse,
|
||
IN OSF_CCALL_STATE InitialCallState,
|
||
IN PRPC_DISPATCH_TABLE DispatchTable,
|
||
IN OSF_CCONNECTION *CConnection
|
||
);
|
||
|
||
void
|
||
FreeCCall (
|
||
IN RPC_STATUS Status
|
||
);
|
||
|
||
RPC_STATUS
|
||
SendCancelPDU(
|
||
);
|
||
|
||
RPC_STATUS
|
||
SendOrphanPDU (
|
||
);
|
||
|
||
RPC_STATUS
|
||
BindToServer (
|
||
BOOL fAsyncBind
|
||
);
|
||
|
||
RPC_STATUS
|
||
Cancel(
|
||
void * ThreadHandle
|
||
);
|
||
|
||
RPC_STATUS
|
||
InqWireIdForSnego (
|
||
OUT unsigned char *WireId
|
||
);
|
||
|
||
RPC_STATUS
|
||
BindingHandleToAsyncHandle (
|
||
OUT void **AsyncHandle
|
||
);
|
||
|
||
// if fMultipleBindingsAvailable is set, the return value is a head of a linked
|
||
// list. If fMultipleBindingsAvailable is FALSE, only the element in the return
|
||
// value is meaningful
|
||
inline OSF_BINDING *
|
||
GetListOfAvaialbleBindings (
|
||
OUT BOOL *fMultipleBindingsAvailable
|
||
)
|
||
{
|
||
if (Bindings.AvailableBindingsList)
|
||
{
|
||
*fMultipleBindingsAvailable = TRUE;
|
||
return Bindings.AvailableBindingsList;
|
||
}
|
||
else
|
||
{
|
||
*fMultipleBindingsAvailable = FALSE;
|
||
return Bindings.SelectedBinding;
|
||
}
|
||
}
|
||
|
||
RPC_STATUS
|
||
BindCompleteNotify (
|
||
IN p_result_t *OsfResult,
|
||
IN int IndexOfPresentationContextAccepted,
|
||
OUT OSF_BINDING **BindingNegotiated
|
||
);
|
||
|
||
#ifdef DEBUGRPC
|
||
inline void EnterCallback(void)
|
||
{
|
||
CallbackLevel ++;
|
||
}
|
||
|
||
inline void ExitCallback(void)
|
||
{
|
||
CallbackLevel --;
|
||
}
|
||
|
||
inline BOOL IsCallInCallback(void)
|
||
{
|
||
return CallbackLevel > 0;
|
||
}
|
||
#endif
|
||
|
||
private:
|
||
void
|
||
SendFault (
|
||
IN RPC_STATUS Status,
|
||
IN int DidNotExecute
|
||
);
|
||
|
||
#define MAX_ALLOC_Hint 16*1024
|
||
|
||
RPC_STATUS
|
||
EatAuthInfoFromPacket (
|
||
IN rpcconn_request * Request,
|
||
IN OUT UINT * RequestLength
|
||
);
|
||
|
||
BOOL
|
||
ProcessReceivedPDU (
|
||
IN void *Buffer,
|
||
IN int BufferLength
|
||
);
|
||
|
||
RPC_STATUS
|
||
GetCoalescedBuffer (
|
||
IN PRPC_MESSAGE Message,
|
||
IN BOOL BufferValid
|
||
);
|
||
|
||
RPC_STATUS
|
||
SendAlterContextPDU (
|
||
);
|
||
|
||
RPC_STATUS
|
||
GetCoalescedBuffer(
|
||
IN PRPC_MESSAGE Message);
|
||
|
||
RPC_STATUS
|
||
FastSendReceive (
|
||
IN OUT PRPC_MESSAGE Message,
|
||
OUT BOOL *fRetry
|
||
);
|
||
|
||
RPC_STATUS
|
||
SendNextFragment (
|
||
IN unsigned char PacketType = rpc_request,
|
||
IN BOOL fFirstSend = TRUE,
|
||
OUT void **ReceiveBuffer = 0,
|
||
OUT UINT *ReceivedLength = 0
|
||
);
|
||
|
||
RPC_STATUS
|
||
ActuallyProcessPDU (
|
||
IN rpcconn_common *Packet,
|
||
IN UINT PacketLength,
|
||
IN OUT PRPC_MESSAGE Message,
|
||
IN BOOL fAsync = 0,
|
||
OUT BOOL *pfSubmitReceive = NULL
|
||
);
|
||
|
||
RPC_STATUS
|
||
ProcessResponse (
|
||
IN rpcconn_response *Packet,
|
||
IN PRPC_MESSAGE Message,
|
||
OUT BOOL *pfSubmitReceive
|
||
);
|
||
|
||
RPC_STATUS
|
||
ProcessRequestOrResponse (
|
||
IN rpcconn_request *Request,
|
||
IN UINT PacketLength,
|
||
IN BOOL fRequest,
|
||
IN PRPC_MESSAGE Message
|
||
);
|
||
|
||
RPC_STATUS
|
||
DealWithCallback (
|
||
IN rpcconn_request *Request,
|
||
IN PRPC_MESSAGE Message
|
||
);
|
||
|
||
RPC_STATUS
|
||
ReceiveReply (
|
||
IN rpcconn_request *Request,
|
||
IN PRPC_MESSAGE Message
|
||
);
|
||
|
||
void
|
||
CallFailed (
|
||
IN RPC_STATUS Status
|
||
) ;
|
||
|
||
int
|
||
QueueBuffer (
|
||
IN void *Buffer,
|
||
IN int BufferLength);
|
||
|
||
BOOL
|
||
IssueNotification (
|
||
IN RPC_ASYNC_EVENT Event = RpcCallComplete
|
||
);
|
||
|
||
RPC_STATUS ReserveSpaceForSecurityIfNecessary (void);
|
||
|
||
void UpdateObjectUUIDInfo (IN UUID *ObjectUuid);
|
||
|
||
void UpdateMaxFragLength (const IN ULONG AuthnLevel);
|
||
|
||
RPC_STATUS AutoRetryCall(IN OUT RPC_MESSAGE *Message, IN BOOL fSendReceivePath,
|
||
IN OSF_BINDING_HANDLE *LocalBindingHandle, IN RPC_STATUS CurrentStatus,
|
||
IN RPC_ASYNC_STATE *AsyncState OPTIONAL);
|
||
|
||
void CleanupOldCallOnAutoRetry(IN PVOID Buffer, IN BOOL fSendReceivePath,
|
||
IN RPC_STATUS CurrentStatus)
|
||
{
|
||
FreeBufferDo(Buffer);
|
||
|
||
if (fSendReceivePath)
|
||
FreeCCall(CurrentStatus);
|
||
else
|
||
{
|
||
//
|
||
// Remove the call reference, CCALL--
|
||
//
|
||
RemoveReference();
|
||
}
|
||
}
|
||
|
||
OSF_BINDING *GetSelectedBinding(void)
|
||
{
|
||
ASSERT(Bindings.SelectedBinding != NULL);
|
||
return Bindings.SelectedBinding;
|
||
}
|
||
|
||
OSF_BINDING *GetBindingList(void)
|
||
{
|
||
ASSERT(Bindings.AvailableBindingsList != NULL);
|
||
return Bindings.AvailableBindingsList;
|
||
}
|
||
|
||
void *
|
||
ActualBuffer (
|
||
IN void *Buffer
|
||
);
|
||
|
||
RPC_STATUS
|
||
CallCancelled (
|
||
OUT PDWORD Timeout
|
||
);
|
||
|
||
RPC_STATUS
|
||
RegisterCallForCancels (
|
||
);
|
||
|
||
void
|
||
UnregisterCallForCancels (
|
||
);
|
||
|
||
void * operator new (
|
||
size_t allocBlock,
|
||
unsigned int xtraBytes
|
||
);
|
||
|
||
RPC_STATUS
|
||
UpdateBufferSize (
|
||
IN OUT void **Buffer,
|
||
IN int CurrentBufferLength
|
||
);
|
||
|
||
inline BOOL
|
||
fOkToAdvanceCall()
|
||
{
|
||
return (fAdvanceCallCount.Increment() == 2);
|
||
}
|
||
|
||
virtual RPC_STATUS
|
||
InqSecurityContext (
|
||
OUT void **SecurityContextHandle
|
||
);
|
||
|
||
static RPC_STATUS
|
||
NegotiateTransferSyntaxAndGetBuffer (
|
||
IN OUT PRPC_MESSAGE Message,
|
||
IN UUID *ObjectUuid
|
||
);
|
||
|
||
inline ULONG
|
||
GetBindingHandleTimeout (
|
||
IN OSF_BINDING_HANDLE *BindingToUse
|
||
)
|
||
{
|
||
RPC_STATUS RpcStatus;
|
||
ULONG_PTR OptionValue;
|
||
|
||
RpcStatus = BindingToUse->OSF_BINDING_HANDLE::InqTransportOption(
|
||
RPC_C_OPT_CALL_TIMEOUT,
|
||
&OptionValue);
|
||
|
||
ASSERT(RpcStatus == RPC_S_OK);
|
||
|
||
if (OptionValue == 0)
|
||
return INFINITE;
|
||
else
|
||
return (ULONG) OptionValue;
|
||
}
|
||
|
||
inline RPC_STATUS
|
||
GetStatusForTimeout (
|
||
IN OSF_BINDING_HANDLE *BindingHandleToUse,
|
||
IN RPC_STATUS Status,
|
||
BOOL fBindingHandleTimeoutUsed
|
||
)
|
||
{
|
||
if (Status == RPC_P_TIMEOUT)
|
||
{
|
||
if (fBindingHandleTimeoutUsed)
|
||
{
|
||
Status = RPC_S_CALL_CANCELLED;
|
||
RpcpErrorAddRecord(EEInfoGCRuntime,
|
||
Status,
|
||
EEInfoDLGetStatusForTimeout10,
|
||
RPC_P_TIMEOUT,
|
||
GetBindingHandleTimeout(BindingHandle));
|
||
}
|
||
else
|
||
{
|
||
Status = RPC_S_CALL_FAILED_DNE;
|
||
RpcpErrorAddRecord(EEInfoGCRuntime,
|
||
Status,
|
||
EEInfoDLGetStatusForTimeout20,
|
||
(ULONG)RPC_P_TIMEOUT,
|
||
(ULONG)RPC_C_SERVER_BIND_TIMEOUT);
|
||
}
|
||
}
|
||
|
||
return Status;
|
||
}
|
||
|
||
inline ULONG
|
||
GetEffectiveTimeoutForBind (
|
||
IN OSF_BINDING_HANDLE *BindingToUse,
|
||
OUT BOOL *fBindingHandleTimeoutUsed
|
||
)
|
||
{
|
||
ULONG Timeout;
|
||
|
||
Timeout = GetBindingHandleTimeout(BindingToUse);
|
||
if (Timeout > RPC_C_SERVER_BIND_TIMEOUT)
|
||
{
|
||
Timeout = RPC_C_SERVER_BIND_TIMEOUT;
|
||
*fBindingHandleTimeoutUsed = FALSE;
|
||
}
|
||
else
|
||
{
|
||
*fBindingHandleTimeoutUsed = TRUE;
|
||
}
|
||
|
||
return Timeout;
|
||
}
|
||
};
|
||
|
||
inline void *
|
||
OSF_CCALL::operator new (
|
||
size_t allocBlock,
|
||
unsigned int xtraBytes
|
||
)
|
||
{
|
||
I_RPC_HANDLE pvTemp = (I_RPC_HANDLE) new char[allocBlock + xtraBytes];
|
||
|
||
return(pvTemp);
|
||
}
|
||
|
||
inline void
|
||
OSF_CCALL::FreeObject (
|
||
)
|
||
{
|
||
if (AsyncStatus == RPC_S_ASYNC_CALL_PENDING)
|
||
{
|
||
AsyncStatus = RPC_S_CALL_FAILED;
|
||
}
|
||
|
||
FreeCCall(AsyncStatus);
|
||
}
|
||
|
||
inline RPC_STATUS
|
||
OSF_CCALL::RegisterCallForCancels (
|
||
)
|
||
{
|
||
RPC_STATUS Status;
|
||
|
||
if (pAsync == 0)
|
||
{
|
||
Status = RegisterForCancels(this);
|
||
if (Status != RPC_S_OK)
|
||
{
|
||
return Status;
|
||
}
|
||
|
||
if (ThreadGetRpcCancelTimeout() == RPC_C_CANCEL_INFINITE_TIMEOUT)
|
||
{
|
||
CancelState = CANCEL_INFINITE;
|
||
}
|
||
else
|
||
{
|
||
CancelState = CANCEL_NOTINFINITE;
|
||
}
|
||
}
|
||
return RPC_S_OK;
|
||
}
|
||
|
||
inline void
|
||
OSF_CCALL::UnregisterCallForCancels (
|
||
)
|
||
{
|
||
if (pAsync == 0)
|
||
{
|
||
EVAL_AND_ASSERT(RPC_S_OK == UnregisterForCancels());
|
||
}
|
||
}
|
||
|
||
|
||
inline void *
|
||
OSF_CCALL::ActualBuffer (
|
||
IN void *Buffer
|
||
)
|
||
{
|
||
ASSERT (HeaderSize != 0);
|
||
if (UuidSpecified)
|
||
{
|
||
Buffer = (char *) Buffer - sizeof(rpcconn_request) - sizeof(UUID);
|
||
}
|
||
else
|
||
{
|
||
Buffer = (char *) Buffer - sizeof(rpcconn_request);
|
||
}
|
||
|
||
return Buffer;
|
||
}
|
||
|
||
inline int
|
||
OSF_CCALL::QueueBuffer (
|
||
IN void *Buffer,
|
||
IN int BufferLength
|
||
)
|
||
{
|
||
RcvBufferLength += BufferLength;
|
||
|
||
return BufferQueue.PutOnQueue(Buffer, BufferLength);
|
||
}
|
||
|
||
NEW_SDICT2(OSF_CCALL, PVOID);
|
||
|
||
#define SYNC_CONN_FREE 0
|
||
#define SYNC_CONN_BUSY -1
|
||
#define ASYNC_CONN_BUSY -2
|
||
#define ASYNC_CONN_FREE -3
|
||
|
||
enum CONNECTION_STATES
|
||
{
|
||
ConnUninitialized,
|
||
ConnAborted,
|
||
ConnOpen
|
||
};
|
||
|
||
const unsigned int FreshFromCache = 1;
|
||
|
||
enum FAILURE_COUNT_STATE
|
||
{
|
||
FailureCountUnknown,
|
||
FailureCountNotExceeded,
|
||
FailureCountExceeded
|
||
};
|
||
|
||
|
||
class OSF_CCONNECTION : public REFERENCED_OBJECT
|
||
/*++
|
||
|
||
Class Description:
|
||
This class encapsulates a transport connection. The transport
|
||
connection may be used by one or more RPC calls. Each RPC
|
||
call is encapsulated by an CALL object. This object may
|
||
be exclusively used by a call. Each connection is owned by
|
||
exacly one thread (ie: all calls on a connection have been
|
||
initiated by a single thread).
|
||
|
||
Fields:
|
||
Association: Pointer to the association object
|
||
|
||
ConnectionKey: Key to our entry in the dictionary of connections in
|
||
the association.
|
||
|
||
ThreadId: Thread Id of the thread owning this call.
|
||
|
||
DceSecurityInfo - Contains information necessary for DCE security to
|
||
work properly. This includes the association uuid (a different
|
||
value for each connection), and sequence numbers (both directions).
|
||
|
||
ThirdLegAuthNeeded - Contains a flag indicating whether or not third
|
||
leg authentication is needed; a non-zero value indicates that it
|
||
is needed.
|
||
|
||
ClientSecurityContext - Optionally contains the security context being
|
||
used for this connection.
|
||
|
||
AdditionalSpaceForSecurity - Contains the amount of space to save
|
||
for security in each buffer we allocate.
|
||
|
||
LastTimeUsed - Contains the time in seconds when this connection was
|
||
last used.
|
||
|
||
CurrentCall - The call on which we are currently **sending** data
|
||
|
||
ClientInfo - Contains the pointers to the loadable transport routines
|
||
for the transport type of this connection.
|
||
|
||
fConnectionAborted - If this field is non-zero it indicates that the
|
||
connection has been aborted, meaning that any attempts to send
|
||
or receive data on the connection will fail.
|
||
|
||
--*/
|
||
{
|
||
friend class OSF_CASSOCIATION;
|
||
friend class OSF_CCALL;
|
||
friend class OSF_BINDING_HANDLE;
|
||
|
||
private:
|
||
OSF_CASSOCIATION * Association;
|
||
OSF_CCALL *CurrentCall ;
|
||
int ConnectionKey;
|
||
CONNECTION_STATES State;
|
||
unsigned char WireAuthId;
|
||
unsigned short MaxFrag;
|
||
ULONG ThreadId ;
|
||
BOOL CachedCCallAvailable ;
|
||
ULONG MaxSavedHeaderSize;
|
||
OSF_CCALL *CachedCCall ;
|
||
ULONG SavedHeaderSize;
|
||
unsigned int ComTimeout ;
|
||
void * SavedHeader;
|
||
BOOL AdditionalLegNeeded;
|
||
ULONG LastTimeUsed;
|
||
UINT TokenLength;
|
||
UINT AdditionalSpaceForSecurity;
|
||
BOOL fIdle ;
|
||
BOOL fExclusive ;
|
||
BOOL fConnectionAborted;
|
||
CompositeFlags Flags;
|
||
|
||
BITSET Bindings;
|
||
QUEUE CallQueue ;
|
||
MUTEX ConnMutex ;
|
||
OSF_CCALL_DICT2 ActiveCalls ;
|
||
SECURITY_CONTEXT ClientSecurityContext;
|
||
|
||
RPC_CONNECTION_TRANSPORT * ClientInfo;
|
||
union
|
||
{
|
||
void *ConnSendContext ;
|
||
OSF_CCONNECTION *NextConnection; // used to link connections in some case
|
||
} u;
|
||
|
||
DCE_SECURITY_INFO DceSecurityInfo;
|
||
|
||
void *BufferToFree;
|
||
BOOL ConnectionReady;
|
||
BOOL fSeparateConnection;
|
||
|
||
public:
|
||
OSF_CCONNECTION (
|
||
IN OSF_CASSOCIATION *Association,
|
||
IN RPC_CONNECTION_TRANSPORT * RpcClientInfo,
|
||
IN unsigned int Timeout,
|
||
IN CLIENT_AUTH_INFO * myAuthInfo,
|
||
IN BOOL fExclusive,
|
||
IN BOOL fSeparateConnection,
|
||
OUT RPC_STATUS * pStatus
|
||
);
|
||
|
||
virtual ~OSF_CCONNECTION (
|
||
);
|
||
|
||
virtual void
|
||
ProcessSendComplete (
|
||
IN RPC_STATUS EventStatus,
|
||
IN BUFFER Buffer
|
||
);
|
||
|
||
RPC_STATUS
|
||
TransInitialize (
|
||
IN RPC_CHAR *NetworkAddress,
|
||
IN RPC_CHAR *NetworkOptions
|
||
)
|
||
{
|
||
if (ClientInfo->Initialize)
|
||
{
|
||
return ClientInfo->Initialize(TransConnection(),
|
||
NetworkAddress,
|
||
NetworkOptions,
|
||
(fExclusive == 0));
|
||
}
|
||
|
||
return (RPC_S_OK);
|
||
}
|
||
|
||
void
|
||
TransInitComplete (
|
||
)
|
||
{
|
||
if (ClientInfo->InitComplete)
|
||
{
|
||
ClientInfo->InitComplete(TransConnection());
|
||
}
|
||
}
|
||
|
||
RPC_STATUS
|
||
TransOpen (
|
||
IN OSF_BINDING_HANDLE * BindingHandle,
|
||
IN RPC_CHAR * RpcProtocolSequence,
|
||
IN RPC_CHAR * NetworkAddress,
|
||
IN RPC_CHAR * Endpoint,
|
||
IN RPC_CHAR * NetworkOptions,
|
||
IN void *ResolverHint,
|
||
IN BOOL fHintInitialized,
|
||
IN ULONG Timeout
|
||
) ;
|
||
|
||
RPC_STATUS
|
||
TransReceive (
|
||
OUT void * * Buffer,
|
||
OUT unsigned int * BufferLength,
|
||
IN ULONG Timeout
|
||
);
|
||
|
||
RPC_STATUS
|
||
TransSend (
|
||
IN void * Buffer,
|
||
IN unsigned int BufferLength,
|
||
IN BOOL fDisableShutdownCheck,
|
||
IN BOOL fDisableCancelCheck,
|
||
IN ULONG Timeout
|
||
);
|
||
|
||
#ifdef WIN96
|
||
RPC_STATUS
|
||
TransClose (
|
||
);
|
||
#endif
|
||
|
||
RPC_STATUS
|
||
TransSendReceive (
|
||
IN void * SendBuffer,
|
||
IN unsigned int SendBufferLength,
|
||
OUT void * * ReceiveBuffer,
|
||
OUT unsigned int * ReceiveBufferLength,
|
||
IN ULONG Timeout
|
||
);
|
||
|
||
RPC_STATUS
|
||
TransAsyncSend (
|
||
IN void * SendBuffer,
|
||
IN unsigned int SendBufferLength,
|
||
IN void *SendContext
|
||
) ;
|
||
|
||
RPC_STATUS
|
||
TransAsyncReceive (
|
||
) ;
|
||
|
||
RPC_STATUS
|
||
TransPostEvent (
|
||
IN PVOID Context
|
||
) ;
|
||
|
||
void
|
||
TransAbortConnection (
|
||
);
|
||
|
||
void
|
||
TransClose (
|
||
);
|
||
|
||
unsigned int
|
||
TransMaximumSend (
|
||
);
|
||
|
||
unsigned int
|
||
GuessPacketLength (
|
||
);
|
||
|
||
void * operator new (
|
||
size_t allocBlock,
|
||
unsigned int xtraBytes
|
||
);
|
||
|
||
RPC_STATUS
|
||
TransGetBuffer (
|
||
OUT void * * Buffer,
|
||
IN UINT BufferLength
|
||
);
|
||
|
||
void
|
||
TransFreeBuffer (
|
||
IN void * Buffer
|
||
);
|
||
|
||
RPC_STATUS
|
||
TransReallocBuffer (
|
||
IN OUT void * * Buffer,
|
||
IN UINT OldSize,
|
||
IN UINT NewSize
|
||
);
|
||
|
||
RPC_STATUS
|
||
AllocateCCall (
|
||
OUT OSF_CCALL **CCall
|
||
);
|
||
|
||
RPC_STATUS
|
||
AddCall (
|
||
IN OSF_CCALL *CCall
|
||
);
|
||
|
||
void
|
||
FreeCCall (
|
||
IN OSF_CCALL *CCall,
|
||
IN RPC_STATUS Status,
|
||
IN ULONG ComTimeout
|
||
);
|
||
|
||
RPC_STATUS
|
||
OpenConnectionAndBind (
|
||
IN OSF_BINDING_HANDLE *BindingHandle,
|
||
IN ULONG Timeout,
|
||
IN BOOL fAlwaysNegotiateNDR20,
|
||
OUT FAILURE_COUNT_STATE *fFailureCountExceeded OPTIONAL
|
||
);
|
||
|
||
RPC_STATUS
|
||
ActuallyDoBinding (
|
||
IN OSF_CCALL *CCall,
|
||
IN ULONG MyAssocGroupId,
|
||
IN BOOL fNewConnection,
|
||
IN ULONG Timeout,
|
||
OUT OSF_BINDING **BindingNegotiated,
|
||
OUT BOOL *fPossibleAssociationReset,
|
||
OUT FAILURE_COUNT_STATE *fFailureCountExceeded OPTIONAL
|
||
);
|
||
|
||
RPC_STATUS
|
||
SendBindPacket (
|
||
IN BOOL fInitialPass,
|
||
IN OSF_CCALL *Call,
|
||
IN ULONG AssocGroup,
|
||
IN unsigned char PacketType,
|
||
IN ULONG Timeout,
|
||
IN BOOL fAsync = 1,
|
||
OUT rpcconn_common * * Buffer = 0,
|
||
OUT UINT * BufferLength = 0,
|
||
IN rpcconn_common * InputPacket = 0,
|
||
IN unsigned int InputPacketLength = 0
|
||
);
|
||
|
||
RPC_STATUS
|
||
MaybeDo3rdLegAuth (
|
||
IN void * Buffer,
|
||
IN UINT BufferLength
|
||
);
|
||
|
||
//
|
||
// Set the value of the max frag for the connection.
|
||
//
|
||
void
|
||
SetMaxFrag (
|
||
IN unsigned short max_xmit_frag,
|
||
IN unsigned short max_recv_frag
|
||
);
|
||
|
||
UINT
|
||
InqMaximumFragmentLength (
|
||
);
|
||
|
||
int
|
||
AddPContext (
|
||
IN int PresentContext
|
||
) {return(Bindings.Insert(PresentContext));}
|
||
|
||
void
|
||
DeletePContext (
|
||
IN int PresentContext
|
||
) {Bindings.Delete(PresentContext);}
|
||
|
||
int
|
||
SupportedPContext (
|
||
IN int *PresentationContexts,
|
||
IN int NumberOfPresentationContexts,
|
||
OUT int *PresentationContextSupported
|
||
);
|
||
|
||
int
|
||
SupportedAuthInfo (
|
||
IN CLIENT_AUTH_INFO * ClientAuthInfo,
|
||
IN BOOL fNamedPipe
|
||
);
|
||
|
||
RPC_STATUS
|
||
SendFragment (
|
||
IN rpcconn_common *pFragment,
|
||
IN OSF_CCALL *CCall,
|
||
IN UINT LastFragmentFlag,
|
||
IN UINT HeaderSize,
|
||
IN UINT MaxSecuritySize,
|
||
IN UINT DataLength,
|
||
IN UINT MaximumFragmentLength,
|
||
IN unsigned char *ReservedForSecurity,
|
||
IN BOOL fAsync,
|
||
IN void *SendContext,
|
||
IN ULONG Timeout,
|
||
OUT void **ReceiveBuffer,
|
||
OUT UINT *ReceiveBufferLength
|
||
);
|
||
|
||
void
|
||
ProcessReceiveComplete (
|
||
IN RPC_STATUS EventStatus,
|
||
IN BUFFER Buffer,
|
||
IN UINT BufferLength
|
||
);
|
||
|
||
ULONG
|
||
InquireSendSequenceNumber (
|
||
);
|
||
|
||
ULONG
|
||
InquireReceiveSequenceNumber (
|
||
);
|
||
|
||
RPC_CHAR *InqEndpoint(void);
|
||
|
||
RPC_CHAR *InqNetworkAddress(void);
|
||
|
||
void
|
||
IncSendSequenceNumber (
|
||
);
|
||
|
||
inline void
|
||
IncReceiveSequenceNumber (
|
||
);
|
||
|
||
void
|
||
NotifyCallDeleted (
|
||
);
|
||
|
||
void
|
||
SetLastTimeUsedToNow (
|
||
);
|
||
|
||
ULONG
|
||
InquireLastTimeUsed (
|
||
);
|
||
|
||
ULONG
|
||
GetAssocGroupId (
|
||
);
|
||
|
||
void
|
||
ConnectionAborted (
|
||
IN RPC_STATUS Status,
|
||
IN BOOL fShutdownAssoc = 1
|
||
);
|
||
|
||
void
|
||
AdvanceToNextCall (
|
||
);
|
||
|
||
RPC_STATUS
|
||
AddActiveCall (
|
||
IN ULONG CallId,
|
||
IN OSF_CCALL *CCall
|
||
);
|
||
|
||
RPC_STATUS
|
||
DealWithAlterContextResp (
|
||
IN OSF_CCALL *CCall,
|
||
IN rpcconn_common *Packet,
|
||
IN int PacketLength,
|
||
IN OUT BOOL *AlterContextToNDR20IfNDR64Negotiated
|
||
);
|
||
|
||
void
|
||
MakeConnectionIdle (
|
||
);
|
||
|
||
void
|
||
MakeConnectionActive (
|
||
);
|
||
|
||
BOOL
|
||
IsIdle (
|
||
);
|
||
|
||
void
|
||
DeleteConnection (
|
||
);
|
||
|
||
BOOL IsExclusive (void)
|
||
{
|
||
return fExclusive;
|
||
}
|
||
|
||
RPC_STATUS
|
||
ValidateHeader(
|
||
rpcconn_common * Buffer,
|
||
unsigned long BufferLength
|
||
);
|
||
|
||
RPC_STATUS
|
||
FinishSecurityContextSetup (
|
||
IN OSF_CCALL *Call,
|
||
IN unsigned long AssocGroup,
|
||
OUT rpcconn_common * * Buffer,
|
||
OUT unsigned int * BufferLength,
|
||
IN ULONG Timeout
|
||
);
|
||
|
||
RPC_STATUS
|
||
CallCancelled (
|
||
OUT PDWORD Timeout
|
||
);
|
||
|
||
void
|
||
WaitForSend(
|
||
);
|
||
|
||
BOOL
|
||
MatchModifiedId (
|
||
LUID *pModifiedId
|
||
)
|
||
{
|
||
if (ClientSecurityContext.DefaultLogonId)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
return (FastCompareLUIDAligned(pModifiedId, &ClientSecurityContext.ModifiedId));
|
||
}
|
||
|
||
void
|
||
MaybeAdvanceToNextCall(
|
||
OSF_CCALL *Call
|
||
)
|
||
{
|
||
if (fExclusive == 0
|
||
&& CurrentCall == Call)
|
||
{
|
||
AdvanceToNextCall();
|
||
}
|
||
}
|
||
|
||
RPC_STATUS
|
||
AbortAndWait (
|
||
OSF_CCALL *Call
|
||
)
|
||
{
|
||
int retval;
|
||
|
||
// CCONN++
|
||
AddReference();
|
||
|
||
//
|
||
// There is still a race condition here
|
||
//
|
||
ConnMutex.Request();
|
||
ActiveCalls.Delete(IntToPtr(Call->CallId));
|
||
ConnMutex.Clear();
|
||
|
||
TransAbortConnection();
|
||
|
||
//
|
||
// Wait until only the call reference (and the reference added above)
|
||
// remains
|
||
//
|
||
while (RefCount.GetInteger() > 2)
|
||
{
|
||
SleepEx(1, 0);
|
||
}
|
||
|
||
ASSERT(IsDeleted());
|
||
|
||
TransClose();
|
||
|
||
//
|
||
// Ugly hack alert
|
||
//
|
||
SetNotDeleted();
|
||
|
||
ConnMutex.Request();
|
||
retval = ActiveCalls.Insert(IntToPtr(Call->CallId), Call);
|
||
ConnMutex.Clear();
|
||
|
||
//
|
||
// Don't remove the above reference
|
||
// the connection reference was removed by the thread
|
||
// that did called abort. We are just restoring that reference
|
||
//
|
||
|
||
if (retval == -1)
|
||
{
|
||
return RPC_S_OUT_OF_MEMORY;
|
||
}
|
||
|
||
return RPC_S_OK;
|
||
}
|
||
|
||
inline void SetFreshFromCacheFlag(void)
|
||
{
|
||
Flags.SetFlagUnsafe(FreshFromCache);
|
||
}
|
||
inline void ClearFreshFromCacheFlag(void)
|
||
{
|
||
Flags.ClearFlagUnsafe(FreshFromCache);
|
||
}
|
||
inline BOOL GetFreshFromCacheFlag(void)
|
||
{
|
||
return Flags.GetFlag(FreshFromCache);
|
||
}
|
||
|
||
static void
|
||
OsfDeleteIdleConnections (
|
||
void
|
||
);
|
||
|
||
RPC_STATUS
|
||
TurnOnOffKeepAlives (
|
||
IN BOOL TurnOn,
|
||
IN ULONG Timeout
|
||
);
|
||
|
||
private:
|
||
|
||
inline void
|
||
InitializeWireAuthId (
|
||
IN CLIENT_AUTH_INFO * ClientAuthInfo
|
||
)
|
||
{
|
||
if (ClientAuthInfo)
|
||
WireAuthId = (unsigned char) ClientAuthInfo->AuthenticationService;
|
||
else
|
||
WireAuthId = RPC_C_AUTHN_NONE;
|
||
}
|
||
};
|
||
|
||
inline void *
|
||
OSF_CCONNECTION::operator new (
|
||
size_t allocBlock,
|
||
unsigned int xtraBytes
|
||
)
|
||
{
|
||
I_RPC_HANDLE pvTemp = (I_RPC_HANDLE) new char[allocBlock + xtraBytes];
|
||
|
||
return(pvTemp);
|
||
}
|
||
|
||
#pragma optimize ("t", on)
|
||
inline void
|
||
OSF_CCONNECTION::MakeConnectionIdle (
|
||
)
|
||
{
|
||
LogEvent(SU_CCONN, EV_STOP, this, 0, 0, 1);
|
||
fIdle = 1;
|
||
}
|
||
|
||
inline void
|
||
OSF_CCONNECTION::MakeConnectionActive (
|
||
)
|
||
{
|
||
LogEvent(SU_CCONN, EV_START, this, 0, 0, 1);
|
||
fIdle = 0;
|
||
}
|
||
|
||
inline BOOL
|
||
OSF_CCONNECTION::IsIdle (
|
||
)
|
||
{
|
||
return fIdle;
|
||
}
|
||
|
||
inline void
|
||
OSF_CCONNECTION::NotifyCallDeleted (
|
||
)
|
||
{
|
||
}
|
||
|
||
inline void
|
||
OSF_CCONNECTION::IncSendSequenceNumber (
|
||
)
|
||
{
|
||
DceSecurityInfo.ReceiveSequenceNumber += 1;
|
||
}
|
||
|
||
inline void
|
||
OSF_CCONNECTION::IncReceiveSequenceNumber (
|
||
)
|
||
{
|
||
DceSecurityInfo.ReceiveSequenceNumber += 1;
|
||
}
|
||
|
||
inline ULONG
|
||
OSF_CCONNECTION::InquireSendSequenceNumber (
|
||
)
|
||
{
|
||
return DceSecurityInfo.SendSequenceNumber ;
|
||
}
|
||
|
||
inline ULONG
|
||
OSF_CCONNECTION::InquireReceiveSequenceNumber (
|
||
)
|
||
{
|
||
return DceSecurityInfo.ReceiveSequenceNumber ;
|
||
}
|
||
|
||
|
||
inline int
|
||
OSF_CCONNECTION::SupportedPContext (
|
||
IN int *PresentationContexts,
|
||
IN int NumberOfPresentationContexts,
|
||
OUT int *PresentationContextSupported
|
||
)
|
||
/*++
|
||
|
||
Return Value:
|
||
|
||
Non-zero will be returned if this connection supports the supplied
|
||
presentation context; otherwise, zero will be returned.
|
||
|
||
--*/
|
||
{
|
||
int i;
|
||
int Result;
|
||
|
||
for (i = 0; i < NumberOfPresentationContexts; i ++)
|
||
{
|
||
Result = Bindings.MemberP(PresentationContexts[i]);
|
||
if (Result)
|
||
{
|
||
*PresentationContextSupported = i;
|
||
break;
|
||
}
|
||
}
|
||
return Result;
|
||
}
|
||
|
||
|
||
inline UINT
|
||
OSF_CCONNECTION::InqMaximumFragmentLength (
|
||
)
|
||
/*++
|
||
|
||
Return Value:
|
||
|
||
The maximum fragment length negotiated for this connection will be
|
||
returned.
|
||
|
||
--*/
|
||
{
|
||
return(MaxFrag);
|
||
}
|
||
|
||
#pragma optimize("", on)
|
||
|
||
|
||
|
||
|
||
inline void
|
||
OSF_CCONNECTION::SetLastTimeUsedToNow (
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
We the the last time that this connection was used to now.
|
||
|
||
--*/
|
||
{
|
||
LastTimeUsed = NtGetTickCount();
|
||
}
|
||
|
||
inline ULONG
|
||
OSF_CCONNECTION::InquireLastTimeUsed (
|
||
)
|
||
/*++
|
||
|
||
Return Value:
|
||
|
||
The last time this connection was used will be returned.
|
||
|
||
--*/
|
||
{
|
||
return(LastTimeUsed);
|
||
}
|
||
|
||
|
||
inline RPC_STATUS
|
||
OSF_CCALL::InqSecurityContext (
|
||
OUT void **SecurityContextHandle
|
||
)
|
||
{
|
||
*SecurityContextHandle = Connection->ClientSecurityContext.InqSecurityContext();
|
||
return RPC_S_OK;
|
||
}
|
||
|
||
inline RPC_STATUS
|
||
OSF_CCALL::InqWireIdForSnego (
|
||
OUT unsigned char *WireId
|
||
)
|
||
{
|
||
if ((Connection->ClientSecurityContext.AuthenticationLevel == RPC_C_AUTHN_LEVEL_NONE)
|
||
|| (Connection->ClientSecurityContext.AuthenticationService == RPC_C_AUTHN_NONE))
|
||
return RPC_S_INVALID_BINDING;
|
||
|
||
return Connection->ClientSecurityContext.GetWireIdForSnego(WireId);
|
||
}
|
||
|
||
inline RPC_STATUS
|
||
OSF_CCALL::BindingHandleToAsyncHandle (
|
||
OUT void **AsyncHandle
|
||
)
|
||
{
|
||
if (pAsync == 0)
|
||
return RPC_S_INVALID_BINDING;
|
||
|
||
*AsyncHandle = pAsync;
|
||
return RPC_S_OK;
|
||
}
|
||
|
||
class OSF_BINDING : public MTSyntaxBinding
|
||
{
|
||
public:
|
||
OSF_BINDING (
|
||
IN RPC_SYNTAX_IDENTIFIER *InterfaceId,
|
||
IN TRANSFER_SYNTAX_STUB_INFO *TransferSyntaxInfo,
|
||
IN int CapabilitiesBitmap
|
||
) : MTSyntaxBinding(InterfaceId, TransferSyntaxInfo, CapabilitiesBitmap)
|
||
{
|
||
}
|
||
|
||
inline void SetNextBinding(OSF_BINDING *Next)
|
||
{
|
||
MTSyntaxBinding::SetNextBinding(Next);
|
||
}
|
||
|
||
inline OSF_BINDING *GetNextBinding(void)
|
||
{
|
||
return (OSF_BINDING *)(MTSyntaxBinding::GetNextBinding());
|
||
}
|
||
|
||
inline int CompareWithTransferSyntax (IN const p_syntax_id_t *TransferSyntax)
|
||
{
|
||
return CompareWithTransferSyntax ((RPC_SYNTAX_IDENTIFIER *)TransferSyntax);
|
||
}
|
||
|
||
inline int CompareWithTransferSyntax (IN const RPC_SYNTAX_IDENTIFIER *TransferSyntax)
|
||
{
|
||
return MTSyntaxBinding::CompareWithTransferSyntax ((RPC_SYNTAX_IDENTIFIER *)TransferSyntax);
|
||
}
|
||
|
||
};
|
||
|
||
|
||
NEW_SDICT(OSF_BINDING);
|
||
NEW_SDICT(OSF_CCONNECTION);
|
||
|
||
enum MPX_TYPES
|
||
{
|
||
mpx_unknown,
|
||
mpx_yes,
|
||
mpx_no
|
||
};
|
||
|
||
NEW_SDICT(RPC_TOKEN);
|
||
|
||
|
||
class OSF_CASSOCIATION : public REFERENCED_OBJECT
|
||
/*++
|
||
|
||
Class Description:
|
||
|
||
Fields:
|
||
|
||
MaintainContext - Contains a flag indicating whether or not this
|
||
association needs to keep at least one connection open with
|
||
the server if at all possible. A non-zero value indicates that
|
||
at least one connection should be kept open.
|
||
|
||
CallIdCounter - Contains an interlocked integer used to allocate
|
||
unique call identifiers.
|
||
|
||
BindHandleCount - Counts the number of OSF_BINDING_HANDLEs using
|
||
this association. This particular variable is operated
|
||
with interlocks. However, adding a refcount if you don't have
|
||
one (as in FindOrCreateAssociation - through the global data
|
||
structure) requires holding AssocDictMutex.
|
||
--*/
|
||
{
|
||
friend class OSF_CCONNECTION;
|
||
friend class OSF_CCALL;
|
||
friend class OSF_BINDING_HANDLE;
|
||
|
||
private:
|
||
DCE_BINDING * DceBinding;
|
||
INTERLOCKED_INTEGER BindHandleCount;
|
||
ULONG AssocGroupId;
|
||
OSF_BINDING_DICT Bindings;
|
||
OSF_CCONNECTION_DICT ActiveConnections;
|
||
|
||
TRANS_INFO *TransInfo ;
|
||
unsigned char * SecondaryEndpoint;
|
||
int Key;
|
||
UINT OpenConnectionCount;
|
||
UINT ConnectionsDoingBindCount;
|
||
BOOL fPossibleServerReset;
|
||
|
||
UINT MaintainContext;
|
||
ULONG CallIdCounter;
|
||
|
||
MUTEX AssociationMutex;
|
||
|
||
BOOL AssociationValid;
|
||
|
||
// in some cases we will decide that the association is dead,
|
||
// and we will mark it as such so that other calls can
|
||
// quickly fail instead of banging against a dead server.
|
||
// The error with which the association was shutdown is
|
||
// stored here. Callers that implement quick failure detection
|
||
// can read it off here. This is valid only if
|
||
// AssociationValid == FALSE.
|
||
RPC_STATUS AssociationShutdownError;
|
||
|
||
BOOL DontLinger;
|
||
|
||
BOOL ResolverHintInitialized;
|
||
|
||
// protected by the AssociationMutex
|
||
BOOL fIdleConnectionCleanupNeeded;
|
||
|
||
int FailureCount;
|
||
MPX_TYPES fMultiplex;
|
||
unsigned long SavedDrep;
|
||
RPC_TOKEN_DICT TokenDict;
|
||
|
||
union
|
||
{
|
||
struct
|
||
{
|
||
// TRUE if this is an association without binding handle
|
||
// references to it (i.e. it is lingered), FALSE
|
||
// otherwise. Protected by the AssocDictMutex
|
||
BOOL fAssociationLingered;
|
||
|
||
// The timestamp for garbage collecting this item. Defined
|
||
// only if fAssociationLingered == TRUE. Protected by the
|
||
// AssocDictMutex
|
||
DWORD Timestamp;
|
||
} Linger;
|
||
|
||
// this arm of the union is used only during destruction - never use
|
||
// it outside
|
||
OSF_CASSOCIATION *NextAssociation;
|
||
};
|
||
|
||
public:
|
||
|
||
OSF_CASSOCIATION (
|
||
IN DCE_BINDING * DceBinding,
|
||
IN TRANS_INFO *TransInfo,
|
||
IN OUT RPC_STATUS * RpcStatus
|
||
);
|
||
|
||
~OSF_CASSOCIATION (
|
||
);
|
||
|
||
public:
|
||
|
||
#if 0
|
||
void
|
||
CleanupAuthenticatedConnections(
|
||
IN CLIENT_AUTH_INFO *ClientAuthInfo
|
||
);
|
||
#endif
|
||
|
||
void
|
||
UnBind ( // Decrement the BindingCount, and clean up the
|
||
// association if it reaches zero.
|
||
);
|
||
|
||
RPC_STATUS
|
||
FindOrCreateOsfBinding (
|
||
IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation,
|
||
IN RPC_MESSAGE *Message,
|
||
OUT int *NumberOfBindings,
|
||
IN OUT OSF_BINDING *BindingsForThisInterface[]
|
||
);
|
||
|
||
BOOL
|
||
DoesBindingForInterfaceExist (
|
||
IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation
|
||
);
|
||
|
||
RPC_STATUS
|
||
AllocateCCall (
|
||
IN OSF_BINDING_HANDLE *BindingHandle,
|
||
IN PRPC_MESSAGE Message,
|
||
IN CLIENT_AUTH_INFO * ClientAuthInfo,
|
||
OUT OSF_CCALL ** CCall,
|
||
OUT BOOL *fBindingHandleReferenceRemoved
|
||
);
|
||
|
||
private:
|
||
|
||
RPC_STATUS
|
||
ProcessBindAckOrNak (
|
||
IN rpcconn_common *Buffer,
|
||
IN UINT BufferLength,
|
||
IN OSF_CCONNECTION *CConnection,
|
||
IN OSF_CCALL *CCall,
|
||
OUT ULONG *NewGroupId,
|
||
OUT OSF_BINDING **BindingNegotiated,
|
||
OUT FAILURE_COUNT_STATE *fFailureCountExceeded OPTIONAL
|
||
);
|
||
|
||
OSF_CCONNECTION *
|
||
LookForExistingConnection (
|
||
IN OSF_BINDING_HANDLE *BindingHandle,
|
||
IN BOOL fExclusive,
|
||
IN CLIENT_AUTH_INFO *ClientAuthInfo,
|
||
IN int *PresentContext,
|
||
IN int NumberOfPresentationContexts,
|
||
OUT int *PresentationContextSupported,
|
||
OUT OSF_CCALL_STATE *InitialCallState,
|
||
IN BOOL fNonCausal
|
||
);
|
||
|
||
inline void
|
||
ClearIdleConnectionCleanupFlag (
|
||
void
|
||
)
|
||
{
|
||
AssociationMutex.VerifyOwned();
|
||
|
||
if (fIdleConnectionCleanupNeeded)
|
||
{
|
||
fIdleConnectionCleanupNeeded = FALSE;
|
||
if (InterlockedDecrement(&PeriodicGarbageCollectItems) == 0)
|
||
{
|
||
#if defined (RPC_GC_AUDIT)
|
||
DbgPrintEx(77, DPFLTR_WARNING_LEVEL, "%d (0x%X) PeriodicGarbageCollectItems dropped to 0 (a)\n",
|
||
GetCurrentProcessId(), GetCurrentProcessId());
|
||
#endif
|
||
}
|
||
}
|
||
}
|
||
|
||
public:
|
||
|
||
int
|
||
CompareWithDceBinding (
|
||
IN DCE_BINDING * DceBinding,
|
||
OUT BOOL *fOnlyEndpointDifferent
|
||
);
|
||
|
||
//
|
||
// Note, whoever calls this routine must have already
|
||
// requested the AssociationDictMutex.
|
||
//
|
||
void
|
||
IncrementCount (
|
||
void
|
||
)
|
||
{
|
||
LogEvent(SU_CASSOC, EV_INC, this, (PVOID)2, BindHandleCount.GetInteger(), 1, 0);
|
||
BindHandleCount.Increment();
|
||
}
|
||
|
||
void
|
||
ShutdownRequested (
|
||
IN RPC_STATUS AssociationShutdownError OPTIONAL,
|
||
IN OSF_CCONNECTION *ExemptConnection OPTIONAL
|
||
);
|
||
|
||
inline OSF_BINDING *
|
||
FindBinding (
|
||
IN int PresentContext
|
||
)
|
||
{
|
||
return(Bindings.Find(PresentContext));
|
||
}
|
||
|
||
virtual RPC_STATUS
|
||
ToStringBinding (
|
||
OUT RPC_CHAR * * StringBinding,
|
||
IN RPC_UUID * ObjectUuid
|
||
);
|
||
|
||
OSF_CCONNECTION *
|
||
FindIdleConnection (
|
||
void
|
||
);
|
||
|
||
void
|
||
MaintainingContext (
|
||
);
|
||
|
||
DCE_BINDING *
|
||
DuplicateDceBinding (
|
||
);
|
||
|
||
BOOL
|
||
IsValid (
|
||
);
|
||
|
||
BOOL
|
||
ConnectionAborted (
|
||
IN OSF_CCONNECTION *Connection
|
||
);
|
||
|
||
void
|
||
NotifyConnectionOpen (
|
||
);
|
||
|
||
void
|
||
NotifyConnectionClosed (
|
||
);
|
||
|
||
void NotifyConnectionBindInProgress (
|
||
void
|
||
);
|
||
|
||
void NotifyConnectionBindCompleted (
|
||
void
|
||
);
|
||
|
||
void * operator new (
|
||
size_t allocBlock,
|
||
unsigned int xtraBytes
|
||
);
|
||
|
||
int
|
||
CompareResolverHint (
|
||
void *Hint
|
||
);
|
||
|
||
void *
|
||
InqResolverHint (
|
||
);
|
||
|
||
void
|
||
SetResolverHint (
|
||
void *Hint
|
||
);
|
||
|
||
void
|
||
FreeResolverHint (
|
||
void *Hint
|
||
);
|
||
|
||
inline BOOL
|
||
IsResolverHintSynchronizationNeeded (
|
||
void
|
||
);
|
||
|
||
inline void
|
||
ResetAssociation (
|
||
)
|
||
{
|
||
AssocGroupId = 0;
|
||
if (ResolverHintInitialized)
|
||
{
|
||
ResolverHintInitialized = FALSE;
|
||
FreeResolverHint(InqResolverHint());
|
||
}
|
||
}
|
||
|
||
BOOL
|
||
IsAssociationReset ( void )
|
||
{
|
||
return (AssocGroupId == 0);
|
||
}
|
||
|
||
RPC_STATUS
|
||
FindOrCreateToken (
|
||
IN HANDLE hToken,
|
||
IN LUID *pLuid,
|
||
OUT RPC_TOKEN **ppToken,
|
||
OUT BOOL *pfTokenFound
|
||
);
|
||
|
||
void
|
||
ReferenceToken(
|
||
IN RPC_TOKEN *pToken
|
||
);
|
||
|
||
void
|
||
DereferenceToken(
|
||
IN RPC_TOKEN *pToken
|
||
);
|
||
|
||
void
|
||
CleanupConnectionList(
|
||
IN RPC_TOKEN *pToken
|
||
);
|
||
|
||
static void
|
||
OsfDeleteLingeringAssociations (
|
||
void
|
||
);
|
||
|
||
inline BOOL
|
||
GetDontLingerState (
|
||
void
|
||
)
|
||
{
|
||
return DontLinger;
|
||
}
|
||
|
||
inline void
|
||
SetDontLingerState (
|
||
IN BOOL DontLinger
|
||
)
|
||
{
|
||
ASSERT(DontLinger == TRUE);
|
||
ASSERT(this->DontLinger == FALSE);
|
||
this->DontLinger = DontLinger;
|
||
}
|
||
};
|
||
|
||
inline int
|
||
OSF_CASSOCIATION::CompareResolverHint (
|
||
void *Hint
|
||
)
|
||
{
|
||
RPC_CONNECTION_TRANSPORT *ClientInfo =
|
||
(RPC_CONNECTION_TRANSPORT *) TransInfo->InqTransInfo();
|
||
|
||
if (ClientInfo->CompareResolverHint)
|
||
{
|
||
return ClientInfo->CompareResolverHint(TransResolverHint(), Hint);
|
||
}
|
||
else
|
||
{
|
||
return RpcpMemoryCompare(TransResolverHint(), Hint, ClientInfo->ResolverHintSize);
|
||
}
|
||
}
|
||
|
||
inline void *
|
||
OSF_CASSOCIATION::InqResolverHint (
|
||
)
|
||
{
|
||
return TransResolverHint();
|
||
}
|
||
|
||
inline void
|
||
OSF_CASSOCIATION::SetResolverHint (
|
||
void *Hint
|
||
)
|
||
{
|
||
RPC_CONNECTION_TRANSPORT *ClientInfo =
|
||
(RPC_CONNECTION_TRANSPORT *) TransInfo->InqTransInfo();
|
||
|
||
if (ClientInfo->CopyResolverHint)
|
||
{
|
||
if (TransResolverHint() != Hint)
|
||
{
|
||
ClientInfo->CopyResolverHint(TransResolverHint(),
|
||
Hint,
|
||
TRUE // SourceWillBeAbandoned
|
||
);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
RpcpMemoryCopy(TransResolverHint(), Hint, ClientInfo->ResolverHintSize);
|
||
}
|
||
}
|
||
|
||
inline void
|
||
OSF_CASSOCIATION::FreeResolverHint (
|
||
void *Hint
|
||
)
|
||
{
|
||
RPC_CONNECTION_TRANSPORT *ClientInfo =
|
||
(RPC_CONNECTION_TRANSPORT *) TransInfo->InqTransInfo();
|
||
|
||
if (ClientInfo->FreeResolverHint)
|
||
{
|
||
ClientInfo->FreeResolverHint(Hint);
|
||
}
|
||
}
|
||
|
||
BOOL
|
||
OSF_CASSOCIATION::IsResolverHintSynchronizationNeeded (
|
||
void
|
||
)
|
||
{
|
||
RPC_CONNECTION_TRANSPORT *ClientInfo =
|
||
(RPC_CONNECTION_TRANSPORT *) TransInfo->InqTransInfo();
|
||
|
||
return (ClientInfo->FreeResolverHint != NULL);
|
||
}
|
||
|
||
inline void *
|
||
OSF_CASSOCIATION::operator new (
|
||
size_t allocBlock,
|
||
unsigned int xtraBytes
|
||
)
|
||
{
|
||
I_RPC_HANDLE pvTemp = (I_RPC_HANDLE) new char[allocBlock + xtraBytes];
|
||
|
||
return(pvTemp);
|
||
}
|
||
|
||
inline BOOL
|
||
OSF_CASSOCIATION::IsValid (
|
||
)
|
||
{
|
||
return AssociationValid ;
|
||
}
|
||
|
||
|
||
inline void
|
||
OSF_CASSOCIATION::MaintainingContext (
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is used to indicate that a binding handle using this
|
||
association is maintaining context with the server. This means
|
||
that at least one connection for this association must always be
|
||
open.
|
||
|
||
--*/
|
||
{
|
||
MaintainContext = 1;
|
||
}
|
||
|
||
|
||
inline DCE_BINDING *
|
||
OSF_CASSOCIATION::DuplicateDceBinding (
|
||
)
|
||
{
|
||
return(DceBinding->DuplicateDceBinding());
|
||
}
|
||
|
||
inline ULONG
|
||
OSF_CCONNECTION::GetAssocGroupId (
|
||
)
|
||
{
|
||
return Association->AssocGroupId ;
|
||
}
|
||
|
||
inline void
|
||
OSF_CCONNECTION::WaitForSend (
|
||
)
|
||
{
|
||
while (ConnectionReady == 0)
|
||
{
|
||
//
|
||
// We need a listening thread
|
||
// so the send can complete
|
||
//
|
||
Association->TransInfo->CreateThread();
|
||
Sleep(10);
|
||
}
|
||
|
||
ASSERT(ConnectionReady == 1);
|
||
ConnectionReady = 0;
|
||
}
|
||
|
||
inline void
|
||
OSF_CCONNECTION::DeleteConnection (
|
||
)
|
||
{
|
||
if (fExclusive == 0)
|
||
{
|
||
TransAbortConnection();
|
||
}
|
||
|
||
Delete();
|
||
}
|
||
|
||
inline RPC_CHAR *OSF_CCONNECTION::InqEndpoint(void)
|
||
{
|
||
return Association->DceBinding->InqEndpoint();
|
||
}
|
||
|
||
inline RPC_CHAR *OSF_CCONNECTION::InqNetworkAddress(void)
|
||
{
|
||
return Association->DceBinding->InqNetworkAddress();
|
||
}
|
||
|
||
inline void
|
||
OSF_BINDING_HANDLE::Unbind ()
|
||
{
|
||
BOOL fMutexTaken;
|
||
|
||
// try to take the two mutexes, but if fail on the second, release
|
||
// the first as well and retry, because there is a potential
|
||
// deadlock condition for which this is a workaround
|
||
while (TRUE)
|
||
{
|
||
AssocDictMutex->Request();
|
||
fMutexTaken = Association->AssociationMutex.TryRequest();
|
||
if (fMutexTaken)
|
||
break;
|
||
else
|
||
{
|
||
AssocDictMutex->Clear();
|
||
Sleep(10);
|
||
}
|
||
}
|
||
|
||
if (pToken)
|
||
{
|
||
Association->DereferenceToken(pToken);
|
||
pToken = 0;
|
||
}
|
||
|
||
// unbind will clear the association dict mutex
|
||
// and the association mutex
|
||
Association->UnBind();
|
||
|
||
Association = 0;
|
||
}
|
||
|
||
RPC_STATUS
|
||
LoadableTransportClientInfo (
|
||
IN RPC_CHAR * DllName,
|
||
IN RPC_CHAR * RpcProtocolSequence,
|
||
OUT TRANS_INFO * *ClientTransInfo
|
||
);
|
||
|
||
TRANS_INFO *
|
||
GetLoadedClientTransportInfoFromId (
|
||
IN unsigned short TransportId
|
||
);
|
||
|
||
RPC_STATUS SetAuthInformation (
|
||
IN RPC_BINDING_HANDLE BindingHandle,
|
||
IN CLIENT_AUTH_INFO *AuthInfo
|
||
);
|
||
|
||
// --------------------------------------------------------------------
|
||
|
||
#endif // __OSFCLNT_HXX__
|