Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1317 lines
30 KiB

/*++
Copyright (c) 1991 Microsoft Corporation
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:
--*/
#ifndef __OSFCLNT_HXX__
#define __OSFCLNT_HXX__
class OSF_CCONNECTION;
class OSF_CASSOCIATION;
class OSF_ACTIVE_ENTRY
/*++
Class Description:
This class is used to describe the entries in the dictionary of
active connections maintained by each binding handle.
Fields:
Thread - Contains the thread owning this active connection.
RpcInterfaceInformation - Contains information describing the
interface from which the connection has a call active.
CConnection - Contains the active connection.
--*/
{
friend class OSF_BINDING_HANDLE;
private:
THREAD_IDENTIFIER Thread;
PRPC_CLIENT_INTERFACE RpcInterfaceInformation;
OSF_CCONNECTION * CConnection;
public:
OSF_ACTIVE_ENTRY (
IN THREAD_IDENTIFIER Thread,
IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation,
IN OSF_CCONNECTION * CConnection
);
OSF_CCONNECTION *
IsThisMyActiveConnection (
IN THREAD_IDENTIFIER Thread,
IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation
);
};
inline
OSF_ACTIVE_ENTRY::OSF_ACTIVE_ENTRY (
IN THREAD_IDENTIFIER Thread,
IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation,
IN OSF_CCONNECTION * CConnection
)
/*++
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 active connection.
RpcInterfaceInformation - Supplies information describing the
interface from which the connection has a call active.
CConnection - Supplies the active connection.
--*/
{
this->Thread = Thread;
this->RpcInterfaceInformation = RpcInterfaceInformation;
this->CConnection = CConnection;
}
inline OSF_CCONNECTION *
OSF_ACTIVE_ENTRY::IsThisMyActiveConnection (
IN THREAD_IDENTIFIER Thread,
IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation
)
/*++
Routine Description:
This routine determines if this object contains the active connection
for the specified thread and interface information.
Arguments:
Thread - Supplies the thread.
RpcInterfaceInformation - Supplies the interface information.
Return Value:
If this object contains the active connection 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))
? CConnection : 0));
}
NEW_SDICT(OSF_ACTIVE_ENTRY);
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.
ActiveConnections - This is a dictionary of active connections 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.
--*/
{
private:
OSF_CASSOCIATION * Association;
DCE_BINDING * DceBinding;
RPC_CLIENT_TRANSPORT_INFO * TransportInterface;
OSF_ACTIVE_ENTRY_DICT ActiveConnections;
MUTEX BindingMutex;
unsigned int ReferenceCount;
public:
OSF_BINDING_HANDLE (
IN OUT RPC_STATUS PAPI * RpcStatus
);
~OSF_BINDING_HANDLE (
);
virtual RPC_STATUS
GetBuffer (
IN OUT PRPC_MESSAGE Message
);
virtual RPC_STATUS
BindingCopy (
OUT BINDING_HANDLE * PAPI * DestinationBinding,
IN unsigned int MaintainContext
);
virtual RPC_STATUS
BindingFree (
);
virtual void
PrepareBindingHandle (
IN void * TransportInterface,
IN DCE_BINDING * DceBinding
);
virtual RPC_STATUS
ToStringBinding (
OUT RPC_CHAR PAPI * PAPI * StringBinding
);
virtual RPC_STATUS
ResolveBinding (
IN RPC_CLIENT_INTERFACE PAPI * RpcClientInterface
);
virtual RPC_STATUS
BindingReset (
);
virtual RPC_STATUS
InquireTransportType(
OUT unsigned int PAPI *Type
)
{ *Type = TRANSPORT_TYPE_CN; return(RPC_S_OK); }
virtual unsigned long
MapAuthenticationLevel (
IN unsigned long AuthenticationLevel
);
RPC_STATUS
AllocateConnection (
OUT OSF_CCONNECTION * PAPI * CConnection,
IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation
);
RPC_STATUS
AddActiveEntry (
IN OSF_CCONNECTION * CConnection,
IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation
);
void
FreeConnection (
IN OSF_CCONNECTION * CConnection
);
void
AbortConnection (
IN OSF_CCONNECTION * CConnection
);
void
RemoveActiveConnection (
IN OSF_CCONNECTION * CConnection
);
OSF_CASSOCIATION *
TheAssociation (
) {return(Association);}
};
class OSF_CCONNECTION : public CCONNECTION
/*++
Class Description:
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.
ConnectionAbortedFlag - 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.
Association - Contains a pointer to the association which owns this
connection.
ClientSecurityContext - Optionally contains the security context being
used for this connection.
ThirdLegAuthNeeded - Contains a flag indicating whether or not third
leg authentication is needed; a non-zero value indicates that it
is needed.
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.
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.
FirstCachedBuffer - Contains the first cached buffer.
SecondCachedBuffer - Contains the second cached buffer.
BufferCacheFlags - Contains three flags which control the buffer cache:
a bit indicating whether or not each of the buffers (there are two)
in the cache are available. And a bit indicating whether or not the
cached buffers were allocated.
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).
--*/
{
// This class will only access the AssociationKey member.
friend class OSF_CASSOCIATION;
private:
unsigned short MaxFrag;
BITSET Bindings;
int AssociationKey;
OSF_BINDING_HANDLE * CurrentBinding;
unsigned long CallId;
unsigned long DataRep;
// 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.
unsigned int PresentationContext;
PRPC_DISPATCH_TABLE DispatchTableCallback;
unsigned int ConnectionAbortedFlag;
OSF_CASSOCIATION * Association;
CSECURITY_CONTEXT ClientSecurityContext;
int ThirdLegAuthNeeded;
unsigned int TokenLength;
unsigned int AdditionalSpaceForSecurity;
unsigned long LastTimeUsed;
void PAPI * FirstCachedBuffer;
void PAPI * SecondCachedBuffer;
unsigned int BufferCacheFlags;
unsigned int AlertMsgsSent;
unsigned long SavedHeaderSize;
void PAPI * SavedHeader;
int FirstFrag ;
int FirstReceive ;
unsigned int FragmentLength;
rpcconn_request PAPI * Request ;
unsigned char PacketType ;
unsigned int CurrentBufferLength ;
protected:
DCE_SECURITY_INFO DceSecurityInfo;
// Count of the number of buffer allocated for this connection, but
// not yet freed. Note, this member should actually be protected.
int OutstandingBuffers;
OSF_CCONNECTION (
CLIENT_AUTH_INFO * ClientAuthInfo,
RPC_STATUS PAPI * pStatus
);
public:
// This field is accessed by OSF_BINDING_HANDLE::AllocateConnection
// and OSF_BINDING_HANDLE::RemoveActiveConnection.
int ActiveConnectionsKey;
int PendingAlert;
int AlertsEnabled;
int CallStack;
BOOL EnableCancels ;
virtual~OSF_CCONNECTION (
);
void
SetAssociation (
IN OSF_CASSOCIATION * OwningAssociation
);
// --------------------------------------------------------------------
virtual RPC_STATUS
SendReceive (
IN OUT PRPC_MESSAGE Message
);
RPC_STATUS
SendReceiveRecur (
IN OUT PRPC_MESSAGE Message,
IN unsigned int RecursionCount
);
virtual RPC_STATUS
Send (
IN PRPC_MESSAGE Message
) ;
RPC_STATUS
SendRecur (
IN OUT PRPC_MESSAGE Message,
IN unsigned int RecursionCount
) ;
RPC_STATUS
SendNextChunk(
IN OUT PRPC_MESSAGE Message
) ;
RPC_STATUS
Receive (
IN PRPC_MESSAGE Message,
IN unsigned int Size
) ;
virtual RPC_STATUS // Value to be returned by RpcGetBuffer API.
GetBuffer ( // Perform a buffer allocation operation in a handle specific
// way.
IN OUT PRPC_MESSAGE Message
);
RPC_STATUS
GetBufferDo ( // Actually perform the buffer allocation.
IN unsigned int culRequiredLength,
OUT void PAPI *PAPI * ppBuffer
);
virtual void
FreeBuffer ( // Perform a buffer deallocation operation in a handle
// specific way.
IN PRPC_MESSAGE Message
);
virtual void
FreePipeBuffer (
IN PRPC_MESSAGE Message
) ;
virtual RPC_STATUS
ReallocPipeBuffer (
IN PRPC_MESSAGE Message,
IN unsigned int NewSize
) ;
virtual RPC_STATUS
BindingCopy (
OUT BINDING_HANDLE * PAPI * DestinationBinding,
IN unsigned int MaintainContext
);
// --------------------------------------------------------------------
virtual RPC_STATUS
TransReceive (
OUT void PAPI * PAPI * Buffer,
OUT unsigned int PAPI * BufferLength
) = 0;
virtual RPC_STATUS
TransSend (
IN void PAPI * Buffer,
IN unsigned int BufferLength
) = 0;
virtual RPC_STATUS
TransSendReceive (
IN void PAPI * SendBuffer,
IN unsigned int SendBufferLength,
OUT void PAPI * PAPI * ReceiveBuffer,
OUT unsigned int PAPI * ReceiveBufferLength
) = 0;
virtual RPC_STATUS
TransSendReceiveWithTimeout (
IN void PAPI * SendBuffer,
IN unsigned int SendBufferLength,
OUT void PAPI * PAPI * ReceiveBuffer,
OUT unsigned int PAPI * ReceiveBufferLength,
IN DWORD dwTimeout
) ;
virtual RPC_STATUS
TransSetTimeout (
IN long Timeout
) = 0;
virtual RPC_STATUS
TransGetBuffer (
OUT void PAPI * PAPI * Buffer,
IN unsigned int BufferLength
);
virtual void
TransFreeBuffer (
IN void PAPI * Buffer
);
virtual unsigned int // Returns the maximum size of a send.
TransMaximumSend ( // Returns the maximum size allowed for a send.
) = 0;
// --------------------------------------------------------------------
RPC_STATUS
SendBindPacket ( // Construct and send the bind packet; the reply
// is received, but not decoded. Note, this routine
// will also send an alter context packet.
IN PRPC_SYNTAX_IDENTIFIER InterfaceSyntax,
IN PRPC_SYNTAX_IDENTIFIER TransferSyntaxes,
IN unsigned int TransferSyntaxCount,
IN unsigned char PresentContext,
IN unsigned long AssocGroup,
IN unsigned char PacketType,
OUT void PAPI * PAPI * Buffer, // The buffer should be 0.
OUT unsigned int PAPI * BufferLength
);
void
SetMaxFrag ( // Set the value of the max frag for the connection.
IN unsigned short max_xmit_frag,
IN unsigned short max_recv_frag
);
/* --------------------------------------------------------------------
--------------------------------------------------------------------*/
unsigned int
InqMaximumFragmentLength (
);
int // Indicates success (0), or an error.
AddPContext ( // Add the presentation context to those know for this
// connection.
IN int PresentContext
) {return(Bindings.Insert(PresentContext));}
int
SupportedPContext (
IN int PresentContext
);
int
SupportedAuthInfo (
IN CLIENT_AUTH_INFO * ClientAuthInfo
);
RPC_STATUS
SetAuthInformation (
IN CLIENT_AUTH_INFO * ClientAuthInfo
);
void
SetCurrentBinding (
IN OSF_BINDING_HANDLE * Binding
) {CurrentBinding = Binding;}
RPC_STATUS // Value indicating whether the authentication stuff
// happened correctly (if it exists), and the error if there
// is a problem.
MaybeDo3rdLegAuth ( // Perhaps do the 3rd leg authentication stuff.
IN void PAPI * Buffer,
IN unsigned int BufferLength
);
void
ActivateConnection (
IN unsigned int PresentationContext,
IN PRPC_DISPATCH_TABLE DispatchTable
);
void
FreeConnection (
);
void
AbortConnection (
);
void
SendOrphan (
);
void
SendAlert(
);
RPC_STATUS
PingServer(
) ;
#if defined(NTENV) || defined(DOSWIN32RPC)
RPC_STATUS
Cancel(
void * ThreadHandle
);
unsigned
TestCancel(
);
#endif
private:
// --------------------------------------------------------------------
void
SendFault ( // Send a fault message.
IN RPC_STATUS Status,
IN int DidNotExecute
);
RPC_STATUS
ReceiveMessage (
IN OUT PRPC_MESSAGE Message,
OUT unsigned int PAPI * RemoteFaultOccured,
IN unsigned int Size,
OUT unsigned int PAPI * DidNotExecute
);
#define MAX_ALLOC_Hint 16*1024
RPC_STATUS
EatAuthInfoFromPacket (
IN rpcconn_request PAPI * Request,
IN OUT unsigned int PAPI * RequestLength
);
RPC_STATUS
ReceiveRequestOrResponse (
IN OUT PRPC_MESSAGE Message,
IN unsigned int Size
);
RPC_STATUS
ReceiveNextChunk(
IN OUT PRPC_MESSAGE Message,
IN unsigned int Size,
IN int SecurityFailureOccured = 0
) ;
RPC_STATUS
SendRequestOrResponse (
IN OUT PRPC_MESSAGE Message,
IN unsigned char PacketType,
IN RPC_UUID * ObjectUuid OPTIONAL,
IN int PipeSend = 0
);
RPC_STATUS
SendFragment(
IN OUT rpcconn_common PAPI *pFragment,
IN unsigned int LastFragmentFlag,
IN unsigned int HeaderSize,
IN unsigned int MaxSecuritySize,
IN unsigned int LengthLeft,
IN unsigned int MaximumFragmentLength,
IN unsigned char PAPI *ReservedForSecurity,
OUT void PAPI * PAPI *ReceiveBuffer,
OUT unsigned int PAPI *ReceiveBufferLength
) ;
void
SetLastTimeUsedToNow (
);
unsigned long
InquireLastTimeUsed (
);
RPC_STATUS
DoPreSendProcessing(
) ;
void
DoPostReceiveProcessing(
IN PRPC_MESSAGE Message,
IN RPC_STATUS RpcStatus
) ;
void
DoConnectionCleanup (
IN OUT PRPC_MESSAGE Message,
IN void PAPI *OriginalBuffer,
IN RPC_STATUS RpcStatus,
IN BOOL RemoteFaultOccured,
IN BOOL DidNotExecute
) ;
void
FreeTheConnection (
IN OUT PRPC_MESSAGE Message
) ;
void
AbortTheConnection (
IN OUT PRPC_MESSAGE Message,
IN void PAPI *OriginalBuffer
) ;
};
inline void
OSF_CCONNECTION::FreeTheConnection (
IN OUT PRPC_MESSAGE Message
)
{
if ( (OutstandingBuffers == 0)
&& (CallStack == 0))
{
FreeConnection();
Message->Handle = 0;
}
else
{
Message->Handle = (RPC_BINDING_HANDLE) this;
}
}
inline void
OSF_CCONNECTION::AbortTheConnection (
IN OUT PRPC_MESSAGE Message,
IN void PAPI * OriginalBuffer
)
{
if ( OriginalBuffer )
{
TransFreeBuffer((char PAPI *) OriginalBuffer - sizeof(rpcconn_request));
}
AbortConnection();
Message->Handle = 0;
}
inline void
OSF_CCONNECTION::DoConnectionCleanup(
IN OUT PRPC_MESSAGE Message,
IN void PAPI *OriginalBuffer,
IN RPC_STATUS RpcStatus,
IN BOOL RemoteFaultOccured,
IN BOOL DidNotExecute
)
{
if (EnableCancels && (CallStack == 0))
{
EVAL_AND_ASSERT(RPC_S_OK == UnregisterForCancels());
EnableCancels = 0;
}
if (RpcStatus == RPC_S_OK)
{
FreeTheConnection(Message) ;
return ;
}
if (RemoteFaultOccured)
{
switch (RpcStatus)
{
case RPC_S_OUT_OF_MEMORY:
case RPC_S_UNKNOWN_IF:
case RPC_S_ACCESS_DENIED:
case RPC_S_PROTOCOL_ERROR:
AbortTheConnection(Message, OriginalBuffer) ;
break;
case RPC_S_SERVER_TOO_BUSY:
case RPC_S_PROCNUM_OUT_OF_RANGE:
case RPC_S_UNSUPPORTED_TYPE:
FreeTheConnection (Message);
break;
default:
if (DidNotExecute)
{
// We received an extended error
AbortTheConnection(Message, OriginalBuffer) ;
}
else
{
// We received a user exception
FreeTheConnection(Message) ;
}
}
}
else
{
AbortTheConnection(Message, OriginalBuffer) ;
}
}
inline RPC_STATUS
OSF_CCONNECTION::DoPreSendProcessing(
)
/*++
Routine Description:
Return Value:
--*/
{
RPC_STATUS RpcStatus ;
if (CallStack == 0)
{
EnableCancels = FALSE ;
TransSetTimeout(RPC_C_CANCEL_INFINITE_TIMEOUT);
#ifdef NTENV
if (ThreadGetRpcCancelTimeout() != RPC_C_CANCEL_INFINITE_TIMEOUT)
{
PendingAlert = RpcTestCancel() == RPC_S_OK ? TRUE : FALSE;
if (PendingAlert)
{
return RPC_S_CALL_CANCELLED;
}
RpcStatus = RegisterForCancels(this);
if (RpcStatus != RPC_S_OK)
{
return RpcStatus;
}
EnableCancels = TRUE;
}
else
#endif
{
PendingAlert = FALSE;
}
}
return (RPC_S_OK) ;
}
inline void
OSF_CCONNECTION::DoPostReceiveProcessing(
IN PRPC_MESSAGE Message,
IN RPC_STATUS RpcStatus
)
/*++
Routine Description:
Do the book keeping required after a receive is complete,
WARNING! Do not touch any member privates of the this pointer directly
The *this* pointer could have been deleted [see auto retry logic
in SendReceiveRecur & SendRecur
--*/
{
#ifdef NTENV
if (RpcStatus == RPC_S_OK)
{
if ( ((OSF_CCONNECTION *) Message->Handle)->PendingAlert == TRUE )
{
RpcCancelThread(GetCurrentThread());
((OSF_CCONNECTION *)Message->Handle)->PendingAlert = FALSE;
}
}
#endif
}
inline RPC_STATUS
OSF_CCONNECTION::TransSendReceiveWithTimeout (
IN void PAPI * SendBuffer,
IN unsigned int SendBufferLength,
OUT void PAPI * PAPI * ReceiveBuffer,
OUT unsigned int PAPI * ReceiveBufferLength,
IN DWORD dwTimeout
)
{
ASSERT(0) ;
return RPC_S_INTERNAL_ERROR ;
}
inline void
OSF_CCONNECTION::SetAssociation (
IN OSF_CASSOCIATION * OwningAssociation
)
/*++
Routine Description:
This routine is used to set the association which owns this connection.
We need to do this so that the assocation can be notified when this
connection closes (or when the ConnectionAbortedFlag is set).
Arguments:
OwningAssociation - Supplies the association which owns this
connection.
--*/
{
Association = OwningAssociation;
}
inline void
OSF_CCONNECTION::ActivateConnection (
IN unsigned int PresentationContext,
IN PRPC_DISPATCH_TABLE DispatchTable
)
/*++
Routine Description:
This method is used to activate a connection (make it ready to be
used for making a remote procedure call). We just save the arguments
for later use.
Arguments:
PresentationContext - Supplies the presentation context for this
remote procedure call.
DispatchTable - Supplies the dispatch table to be used for dispatching
callbacks received will making the remote procedure call on this
connection.
--*/
{
this->PresentationContext = PresentationContext;
this->DispatchTableCallback = DispatchTable;
FirstFrag = 1 ;
FirstReceive = 1 ;
}
inline int
OSF_CCONNECTION::SupportedPContext (
IN int PresentContext
)
/*++
Return Value:
Non-zero will be returned if this connection supports the supplied
presentation context; otherwise, zero will be returned.
--*/
{
return(Bindings.MemberP(PresentContext));
}
inline void
OSF_CCONNECTION::SetLastTimeUsedToNow (
)
/*++
Routine Description:
We the the last time that this connection was used to now.
--*/
{
LastTimeUsed = CurrentTimeInSeconds();
}
inline unsigned long
OSF_CCONNECTION::InquireLastTimeUsed (
)
/*++
Return Value:
The last time this connection was used will be returned.
--*/
{
return(LastTimeUsed);
}
inline unsigned int
OSF_CCONNECTION::InqMaximumFragmentLength (
)
/*++
Return Value:
The maximum fragment length negotiated for this connection will be
returned.
--*/
{
return(MaxFrag);
}
class OSF_BINDING
{
friend class OSF_CASSOCIATION;
private:
RPC_CLIENT_INTERFACE RpcInterfaceInformation;
public:
int PresentContext;
OSF_BINDING (
IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation
);
int
CompareWithRpcInterfaceInformation (
IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation
);
};
inline
OSF_BINDING::OSF_BINDING (
IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation
)
/*++
Routine Description:
This constructor really does not deserve a comment. (Someone
will probably say that we (note the royal we) should be fair
and comment this routine because we (again note the royal we)
every other routine.
--*/
{
unsigned int Length;
Length = (RpcInterfaceInformation->Length > sizeof(RPC_SERVER_INTERFACE) ) ?
sizeof(RPC_SERVER_INTERFACE) : RpcInterfaceInformation->Length;
RpcpMemoryCopy(&(this->RpcInterfaceInformation),RpcInterfaceInformation, Length);
}
inline int
OSF_BINDING::CompareWithRpcInterfaceInformation (
IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation
)
/*++
Routine Description:
We compare the specified interface information to the the interface
information in this. This method is used to search a dictionary.
Arguments:
RpcInterfaceInformation - Supplies the interface information to
compare against this.
Return Value:
Zero will be returned if they compare; otherwise, non-zero will
be returned.
--*/
{
unsigned int Length;
Length = (RpcInterfaceInformation->Length > sizeof(RPC_SERVER_INTERFACE) ) ?
sizeof(RPC_SERVER_INTERFACE) : RpcInterfaceInformation->Length;
return(RpcpMemoryCompare(&(this->RpcInterfaceInformation),
RpcInterfaceInformation, Length));
}
NEW_SDICT(OSF_BINDING);
NEW_SDICT(OSF_CCONNECTION);
class OSF_CASSOCIATION
/*++
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.
TaskId - Contains the task identifier of the application which owns
this connection.
--*/
{
friend OSF_CASSOCIATION *
FindOrCreateAssociation (
IN DCE_BINDING * DceBinding,
IN RPC_CLIENT_TRANSPORT_INFO * TransportInterface
);
private:
DCE_BINDING * DceBinding;
int BindHandleCount; // Counts the number of OSF_BINDING_HANDLEs using
// this association. This particular variable is
// protected by the AssociationDictMutex.
OSF_BINDING_DICT Bindings;
OSF_CCONNECTION_DICT FreeConnections;
unsigned long AssocGroupId;
#ifdef WIN
unsigned int TaskId;
#endif
RPC_CLIENT_TRANSPORT_INFO * RpcClientInfo;
unsigned char * SecondaryEndpoint;
int Key;
unsigned int OpenConnectionCount;
unsigned int MaintainContext;
unsigned long CallIdCounter;
//This mutex is *only used* to serialize
//Binds..
MUTEX AssociationMutex;
BOOL AssociationValid ;
int FailureCount ;
public:
OSF_CASSOCIATION (
IN DCE_BINDING * DceBinding,
IN RPC_CLIENT_TRANSPORT_INFO * RpcClientInfo,
IN OUT RPC_STATUS PAPI * RpcStatus
);
~OSF_CASSOCIATION ( // Destructor.
);
private:
RPC_STATUS
ActuallyDoBinding (
IN RPC_SYNTAX_IDENTIFIER PAPI * InterfaceSyntax,
IN RPC_SYNTAX_IDENTIFIER PAPI * TransferSyntaxes,
IN unsigned int TransferSyntaxCount,
OUT OSF_CCONNECTION * PAPI * TheCConnection,
IN int PresentContext,
IN unsigned int Timeout,
IN CLIENT_AUTH_INFO * ClientAuthInfo,
IN unsigned long MyAssocGroupId
);
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.
);
OSF_BINDING *
FindOrCreateOsfBinding (
IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation
);
RPC_STATUS
AllocateConnection (
IN PRPC_CLIENT_INTERFACE RpcInterfaceInformation,
OUT OSF_CCONNECTION * PAPI * CConnection,
IN unsigned int Timeout,
IN CLIENT_AUTH_INFO * ClientAuthInfo
);
int // Indicates success (0), or an out of resources error (-1).
FreeConnection ( // Free a connection (ie. indicate to the association
// that the call using the connection has completed.
IN OSF_CCONNECTION * CConnection
);
RPC_STATUS
PingServer(
) ;
private:
RPC_STATUS // Return value which eventually gets returned from
// RpcBindToInterface.
ProcessBindAckOrNak ( // Process the rpc_bind_ack or rpc_bind_nak
// messages.
IN rpcconn_common PAPI * Buffer,
IN unsigned int BufferLength,
IN OSF_CCONNECTION * CConnection
);
public:
// --------------------------------------------------------------------
int
CompareWithDceBinding (
IN DCE_BINDING * DceBinding
);
// --------------------------------------------------------------------
void
IncrementCount ( // Note, whoever calls this routine must have already
// requested the AssociationDictMutex.
) {BindHandleCount += 1;}
void
ShutdownRequested ( // A connection in the association received a
// shutdown packet.
);
OSF_BINDING *
FindBinding (
IN int PresentContext
) {return(Bindings.Find(PresentContext));}
virtual RPC_STATUS
ToStringBinding (
OUT RPC_CHAR PAPI * PAPI * StringBinding,
IN RPC_UUID * ObjectUuid
);
void
NotifyConnectionClosed (
);
OSF_CCONNECTION *
FindIdleConnection (
IN unsigned long MinimumIdleSeconds,
IN unsigned long CurrentTime
);
void
MaintainingContext (
);
DCE_BINDING *
DuplicateDceBinding (
);
BOOL
IsValid (
) ;
};
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());
}
// --------------------------------------------------------------------
#endif // __OSFCLNT_HXX__