1494 lines
31 KiB
C++
1494 lines
31 KiB
C++
|
/*++
|
|||
|
|
|||
|
Copyright (C) Microsoft Corporation, 1992 - 1999
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
dgsvr.hxx
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This is the server protocol definitions for a datagram rpc.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Dave Steckler (davidst) 15-Dec-1992
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#ifndef __DGSVR_HXX__
|
|||
|
#define __DGSVR_HXX__
|
|||
|
|
|||
|
#define MIN_THREADS_WHILE_ACTIVE 3
|
|||
|
|
|||
|
|
|||
|
// Information on the source endpoint. To be used in
|
|||
|
// forwarding a packet to a dynamic endpoint from the epmapper.
|
|||
|
|
|||
|
// disable "zero-length array" warning
|
|||
|
#pragma warning(disable:4200)
|
|||
|
|
|||
|
struct FROM_ENDPOINT_INFO
|
|||
|
{
|
|||
|
unsigned long FromEndpointLen;
|
|||
|
DREP FromDataRepresentation;
|
|||
|
char FromEndpoint[0];
|
|||
|
};
|
|||
|
|
|||
|
#pragma warning(default:4200)
|
|||
|
|
|||
|
//----------------------------------------------------------------------
|
|||
|
|
|||
|
class DG_SCALL;
|
|||
|
typedef DG_SCALL * PDG_SCALL;
|
|||
|
|
|||
|
class DG_SCONNECTION;
|
|||
|
typedef DG_SCONNECTION * PDG_SCONNECTION;
|
|||
|
|
|||
|
|
|||
|
class DG_ADDRESS : public RPC_ADDRESS
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Class Description:
|
|||
|
|
|||
|
This class represents an endpoint.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
public:
|
|||
|
|
|||
|
#define MIN_FREE_CALLS 2
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
|
|||
|
inline void *
|
|||
|
operator new(
|
|||
|
IN size_t ObjectLength,
|
|||
|
IN TRANS_INFO * Transport
|
|||
|
);
|
|||
|
|
|||
|
DG_ADDRESS(
|
|||
|
TRANS_INFO * LoadableTransport,
|
|||
|
RPC_STATUS * pStatus
|
|||
|
);
|
|||
|
|
|||
|
virtual
|
|||
|
~DG_ADDRESS ();
|
|||
|
|
|||
|
void
|
|||
|
WaitForCalls(
|
|||
|
);
|
|||
|
|
|||
|
virtual void
|
|||
|
EncourageCallCleanup(
|
|||
|
RPC_INTERFACE * Interface
|
|||
|
);
|
|||
|
|
|||
|
virtual RPC_STATUS
|
|||
|
ServerSetupAddress (
|
|||
|
IN RPC_CHAR PAPI *NetworkAddress,
|
|||
|
IN RPC_CHAR PAPI * PAPI *Endpoint,
|
|||
|
IN unsigned int PendingQueueSize,
|
|||
|
IN void PAPI * SecurityDescriptor, OPTIONAL
|
|||
|
IN unsigned long EndpointFlags,
|
|||
|
IN unsigned long NICFlags,
|
|||
|
OUT NETWORK_ADDRESS_VECTOR **ppNetworkAddressVector
|
|||
|
) ;
|
|||
|
|
|||
|
#ifndef NO_PLUG_AND_PLAY
|
|||
|
virtual void PnpNotify();
|
|||
|
#endif
|
|||
|
|
|||
|
virtual RPC_STATUS
|
|||
|
ServerStartingToListen (
|
|||
|
IN unsigned int MinimumCallThreads,
|
|||
|
IN unsigned int MaximumConcurrentCalls
|
|||
|
);
|
|||
|
|
|||
|
virtual void
|
|||
|
ServerStoppedListening (
|
|||
|
);
|
|||
|
|
|||
|
virtual long
|
|||
|
InqNumberOfActiveCalls (
|
|||
|
);
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
CheckThreadPool(
|
|||
|
);
|
|||
|
|
|||
|
inline void
|
|||
|
DispatchPacket(
|
|||
|
DG_PACKET * Packet,
|
|||
|
IN DatagramTransportPair *AddressPair
|
|||
|
);
|
|||
|
|
|||
|
inline PDG_PACKET AllocatePacket();
|
|||
|
|
|||
|
inline void
|
|||
|
FreePacket(
|
|||
|
IN PDG_PACKET pPacket
|
|||
|
);
|
|||
|
|
|||
|
inline PDG_SCALL AllocateCall();
|
|||
|
|
|||
|
inline void
|
|||
|
FreeCall(
|
|||
|
PDG_SCALL pCall
|
|||
|
);
|
|||
|
|
|||
|
DG_SCONNECTION * AllocateConnection();
|
|||
|
|
|||
|
void
|
|||
|
FreeConnection(
|
|||
|
DG_SCONNECTION * Connection
|
|||
|
);
|
|||
|
|
|||
|
RPC_STATUS CompleteListen ();
|
|||
|
|
|||
|
inline RPC_STATUS
|
|||
|
SendPacketBack(
|
|||
|
NCA_PACKET_HEADER * Header,
|
|||
|
unsigned DataAfterHeader,
|
|||
|
DG_TRANSPORT_ADDRESS RemoteAddress
|
|||
|
)
|
|||
|
{
|
|||
|
Header->PacketFlags &= ~DG_PF_FORWARDED;
|
|||
|
Header->PacketFlags2 &= ~DG_PF2_FORWARDED_2;
|
|||
|
|
|||
|
ASSERT( Header->PacketType <= 10 );
|
|||
|
|
|||
|
unsigned Frag = (Header->PacketType << 16) | Header->GetFragmentNumber();
|
|||
|
LogEvent(SU_ADDRESS, EV_PKT_OUT, this, 0, Frag);
|
|||
|
|
|||
|
return Endpoint.TransportInterface->Send(
|
|||
|
Endpoint.TransportEndpoint,
|
|||
|
RemoteAddress,
|
|||
|
0,
|
|||
|
0,
|
|||
|
Header,
|
|||
|
sizeof(NCA_PACKET_HEADER) + DataAfterHeader,
|
|||
|
0,
|
|||
|
0
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
inline void
|
|||
|
SendRejectPacket(
|
|||
|
DG_PACKET * Packet,
|
|||
|
DWORD ErrorCode,
|
|||
|
DG_TRANSPORT_ADDRESS RemoteAddress
|
|||
|
)
|
|||
|
{
|
|||
|
InitErrorPacket(Packet, DG_REJECT, ErrorCode);
|
|||
|
SendPacketBack (&Packet->Header, Packet->GetPacketBodyLen(), RemoteAddress);
|
|||
|
}
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
LaunchReceiveThread(
|
|||
|
);
|
|||
|
|
|||
|
static void
|
|||
|
ScavengerProc(
|
|||
|
void * address
|
|||
|
);
|
|||
|
|
|||
|
inline void
|
|||
|
DecrementActiveCallCount(
|
|||
|
)
|
|||
|
{
|
|||
|
ASSERT(ActiveCallCount < 0xffff0000UL);
|
|||
|
|
|||
|
InterlockedDecrement((LONG *) &ActiveCallCount);
|
|||
|
|
|||
|
Endpoint.NumberOfCalls = ActiveCallCount;
|
|||
|
}
|
|||
|
|
|||
|
inline void
|
|||
|
IncrementActiveCallCount(
|
|||
|
)
|
|||
|
{
|
|||
|
ASSERT( ActiveCallCount < 0x100000 );
|
|||
|
|
|||
|
InterlockedIncrement((LONG *) &ActiveCallCount);
|
|||
|
|
|||
|
Endpoint.NumberOfCalls = ActiveCallCount;
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
BeginAutoListenCall (
|
|||
|
) ;
|
|||
|
|
|||
|
void
|
|||
|
EndAutoListenCall (
|
|||
|
) ;
|
|||
|
|
|||
|
static inline DG_ADDRESS *
|
|||
|
FromEndpoint(
|
|||
|
IN DG_TRANSPORT_ENDPOINT Endpoint
|
|||
|
)
|
|||
|
{
|
|||
|
return CONTAINING_RECORD( Endpoint, DG_ADDRESS, Endpoint.TransportEndpoint );
|
|||
|
}
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
|
|||
|
private:
|
|||
|
|
|||
|
LONG TotalThreadsThisEndpoint;
|
|||
|
LONG ThreadsReceivingThisEndpoint;
|
|||
|
unsigned MinimumCallThreads;
|
|||
|
unsigned MaximumConcurrentCalls;
|
|||
|
|
|||
|
DELAYED_ACTION_NODE ScavengerTimer;
|
|||
|
|
|||
|
unsigned ActiveCallCount;
|
|||
|
|
|||
|
UUID_HASH_TABLE_NODE * CachedConnections;
|
|||
|
|
|||
|
INTERLOCKED_INTEGER AutoListenCallCount;
|
|||
|
|
|||
|
public:
|
|||
|
// this needs to be the last member because the transport endpoint
|
|||
|
// follows it.
|
|||
|
//
|
|||
|
DG_ENDPOINT Endpoint;
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
|
|||
|
unsigned ScavengePackets();
|
|||
|
unsigned ScavengeCalls();
|
|||
|
|
|||
|
private:
|
|||
|
|
|||
|
BOOL
|
|||
|
CaptureClientAddress(
|
|||
|
IN PDG_PACKET Packet,
|
|||
|
OUT DG_TRANSPORT_ADDRESS RemoteAddress
|
|||
|
);
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
ForwardPacket(
|
|||
|
IN PDG_PACKET Packet,
|
|||
|
IN DG_TRANSPORT_ADDRESS RemoteAddress,
|
|||
|
IN char * ServerEndpointString
|
|||
|
);
|
|||
|
|
|||
|
BOOL
|
|||
|
ForwardPacketIfNecessary(
|
|||
|
IN PDG_PACKET pReceivedPacket,
|
|||
|
IN void * pFromEndpoint
|
|||
|
);
|
|||
|
|
|||
|
unsigned short
|
|||
|
ConvertSerialNum(
|
|||
|
IN PDG_PACKET pPacket
|
|||
|
);
|
|||
|
|
|||
|
static inline void
|
|||
|
RemoveIdleConnections(
|
|||
|
DG_ADDRESS * Address
|
|||
|
);
|
|||
|
|
|||
|
};
|
|||
|
|
|||
|
typedef DG_ADDRESS PAPI * PDG_ADDRESS;
|
|||
|
|
|||
|
inline void *
|
|||
|
DG_ADDRESS::operator new(
|
|||
|
IN size_t ObjectLength,
|
|||
|
IN TRANS_INFO * Transport
|
|||
|
)
|
|||
|
{
|
|||
|
RPC_DATAGRAM_TRANSPORT * TransportInterface = (RPC_DATAGRAM_TRANSPORT *) (Transport->InqTransInfo());
|
|||
|
return new char[ObjectLength + TransportInterface->ServerEndpointSize];
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
PDG_PACKET
|
|||
|
DG_ADDRESS::AllocatePacket(
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Allocates a packet and associates it with a particular transport address.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
a packet, or zero if out of memory
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return DG_PACKET::AllocatePacket(Endpoint.Stats.PreferredPduSize);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void
|
|||
|
DG_ADDRESS::FreePacket(
|
|||
|
IN PDG_PACKET pPacket
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Frees a packet. If there are less than MAX_FREE_PACKETS on the
|
|||
|
pre-allocated list, then just add it to the list, otherwise delete it.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pPacket - Packet to delete.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
RPC_S_OK
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
pPacket->Free();
|
|||
|
}
|
|||
|
|
|||
|
class ASSOC_GROUP_TABLE;
|
|||
|
|
|||
|
//
|
|||
|
// casting unsigned to/from void * is OK in this case.
|
|||
|
//
|
|||
|
#pragma warning(push)
|
|||
|
#pragma warning(disable:4312)
|
|||
|
NEW_SDICT2(SECURITY_CONTEXT, unsigned);
|
|||
|
|
|||
|
#pragma warning(pop)
|
|||
|
|
|||
|
|
|||
|
class ASSOCIATION_GROUP : public ASSOCIATION_HANDLE
|
|||
|
//
|
|||
|
// This class represents an association group as defined by OSF. This means
|
|||
|
// a set of associations sharing an address space.
|
|||
|
//
|
|||
|
{
|
|||
|
friend class ASSOC_GROUP_TABLE;
|
|||
|
|
|||
|
public:
|
|||
|
|
|||
|
inline
|
|||
|
ASSOCIATION_GROUP(
|
|||
|
RPC_UUID * pUuid,
|
|||
|
unsigned short InitialPduSize,
|
|||
|
RPC_STATUS * pStatus
|
|||
|
)
|
|||
|
: Mutex(pStatus),
|
|||
|
ASSOCIATION_HANDLE(),
|
|||
|
Node(pUuid),
|
|||
|
CurrentPduSize(InitialPduSize),
|
|||
|
ReferenceCount(1),
|
|||
|
RemoteWindowSize(1)
|
|||
|
{
|
|||
|
ObjectType = DG_SASSOCIATION_TYPE;
|
|||
|
}
|
|||
|
|
|||
|
~ASSOCIATION_GROUP(
|
|||
|
)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
inline static ASSOCIATION_GROUP *
|
|||
|
ContainingRecord(
|
|||
|
UUID_HASH_TABLE_NODE * Node
|
|||
|
)
|
|||
|
{
|
|||
|
return CONTAINING_RECORD (Node, ASSOCIATION_GROUP, Node);
|
|||
|
}
|
|||
|
void
|
|||
|
RequestMutex(
|
|||
|
)
|
|||
|
{
|
|||
|
Mutex.Request();
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
ClearMutex(
|
|||
|
)
|
|||
|
{
|
|||
|
Mutex.Clear();
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
IncrementRefCount(
|
|||
|
)
|
|||
|
{
|
|||
|
long Count = ReferenceCount.Increment();
|
|||
|
LogEvent(SU_ASSOC, EV_INC, this, 0, Count);
|
|||
|
}
|
|||
|
|
|||
|
long
|
|||
|
DecrementRefCount(
|
|||
|
)
|
|||
|
{
|
|||
|
long Count = ReferenceCount.Decrement();
|
|||
|
LogEvent(SU_ASSOC, EV_DEC, this, 0, Count);
|
|||
|
|
|||
|
return Count;
|
|||
|
}
|
|||
|
private:
|
|||
|
|
|||
|
INTERLOCKED_INTEGER ReferenceCount;
|
|||
|
MUTEX Mutex;
|
|||
|
//
|
|||
|
// This lets the object be added to the master ASSOC_GROUP_TABLE.
|
|||
|
//
|
|||
|
UUID_HASH_TABLE_NODE Node;
|
|||
|
|
|||
|
unsigned short CurrentPduSize;
|
|||
|
unsigned short RemoteWindowSize;
|
|||
|
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Scurity callback results.
|
|||
|
//
|
|||
|
// CBI_VALID is true if the callback has occurred.
|
|||
|
// CBI_ALLOWED is true if the callback allowed the user to make the call.
|
|||
|
// CBI_CONTEXT_MASK is bitmask for the context (key sequence number).
|
|||
|
//
|
|||
|
// The remaining bits contain the interface sequence number;
|
|||
|
// (x >> CBI_SEQUENCE_SHIFT) extracts it.
|
|||
|
//
|
|||
|
#define CBI_VALID (0x00000800U)
|
|||
|
#define CBI_ALLOWED (0x00000400U)
|
|||
|
#define CBI_CONTEXT_MASK (0x000000ffU)
|
|||
|
|
|||
|
#define CBI_SEQUENCE_SHIFT 12
|
|||
|
#define CBI_SEQUENCE_MASK (~((1 << CBI_SEQUENCE_SHIFT) - 1))
|
|||
|
|
|||
|
class SECURITY_CALLBACK_INFO_DICT2 : public SIMPLE_DICT2
|
|||
|
{
|
|||
|
public:
|
|||
|
|
|||
|
inline
|
|||
|
SECURITY_CALLBACK_INFO_DICT2 ( // Constructor.
|
|||
|
)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
inline
|
|||
|
~SECURITY_CALLBACK_INFO_DICT2 ( // Destructor.
|
|||
|
)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
inline int
|
|||
|
Update (
|
|||
|
RPC_INTERFACE * Key,
|
|||
|
unsigned Item
|
|||
|
)
|
|||
|
{
|
|||
|
Remove(Key);
|
|||
|
return SIMPLE_DICT2::Insert(Key, UlongToPtr(Item));
|
|||
|
}
|
|||
|
|
|||
|
inline unsigned
|
|||
|
Remove (
|
|||
|
RPC_INTERFACE * Key
|
|||
|
)
|
|||
|
{
|
|||
|
return PtrToUlong(SIMPLE_DICT2::Delete(Key));
|
|||
|
}
|
|||
|
|
|||
|
inline unsigned
|
|||
|
Find (
|
|||
|
RPC_INTERFACE * Key
|
|||
|
)
|
|||
|
{
|
|||
|
return PtrToUlong(SIMPLE_DICT2::Find(Key));
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
class DG_SCALL_TABLE
|
|||
|
{
|
|||
|
public:
|
|||
|
|
|||
|
inline DG_SCALL_TABLE();
|
|||
|
|
|||
|
inline ~DG_SCALL_TABLE();
|
|||
|
|
|||
|
BOOL
|
|||
|
Add(
|
|||
|
PDG_SCALL Call,
|
|||
|
unsigned long Sequence
|
|||
|
);
|
|||
|
|
|||
|
void
|
|||
|
Remove(
|
|||
|
PDG_SCALL Call
|
|||
|
);
|
|||
|
|
|||
|
PDG_SCALL
|
|||
|
Find(
|
|||
|
unsigned long Sequence
|
|||
|
);
|
|||
|
|
|||
|
PDG_SCALL
|
|||
|
Predecessor(
|
|||
|
unsigned long Sequence
|
|||
|
);
|
|||
|
|
|||
|
PDG_SCALL
|
|||
|
Successor(
|
|||
|
PDG_SCALL Call
|
|||
|
);
|
|||
|
|
|||
|
inline void
|
|||
|
RemoveIdleCalls(
|
|||
|
BOOL Aggressive,
|
|||
|
RPC_INTERFACE * Interface
|
|||
|
);
|
|||
|
|
|||
|
private:
|
|||
|
|
|||
|
PDG_SCALL ActiveCallHead;
|
|||
|
PDG_SCALL ActiveCallTail;
|
|||
|
|
|||
|
};
|
|||
|
|
|||
|
inline
|
|||
|
DG_SCALL_TABLE::DG_SCALL_TABLE()
|
|||
|
{
|
|||
|
ActiveCallHead = 0;
|
|||
|
ActiveCallTail = 0;
|
|||
|
}
|
|||
|
|
|||
|
inline
|
|||
|
DG_SCALL_TABLE::~DG_SCALL_TABLE()
|
|||
|
{
|
|||
|
ASSERT( ActiveCallHead == 0 );
|
|||
|
ASSERT( ActiveCallTail == 0 );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
class DG_SCONNECTION : public DG_COMMON_CONNECTION
|
|||
|
{
|
|||
|
public:
|
|||
|
|
|||
|
DG_SCONNECTION *Next;
|
|||
|
|
|||
|
CLIENT_AUTH_INFO AuthInfo;
|
|||
|
|
|||
|
unsigned ActivityHint;
|
|||
|
|
|||
|
ASSOCIATION_GROUP * pAssocGroup;
|
|||
|
|
|||
|
PDG_ADDRESS pAddress;
|
|||
|
RPC_INTERFACE * LastInterface;
|
|||
|
|
|||
|
DG_SCALL * CurrentCall;
|
|||
|
BOOL fFirstCall;
|
|||
|
|
|||
|
enum CALLBACK_STATE
|
|||
|
{
|
|||
|
NoCallbackAttempted = 0x99,
|
|||
|
SetupInProgress,
|
|||
|
MsConvWayAuthInProgress,
|
|||
|
ConvWayAuthInProgress,
|
|||
|
MsConvWay2InProgress,
|
|||
|
ConvWay2InProgress,
|
|||
|
ConvWayInProgress,
|
|||
|
ConvWayAuthMoreInProgress,
|
|||
|
CallbackSucceeded,
|
|||
|
CallbackFailed
|
|||
|
};
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
// The message mutex is only used by ncadg_mq.
|
|||
|
MUTEX3 *pMessageMutex;
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
|
|||
|
DG_SCONNECTION(
|
|||
|
DG_ADDRESS * a_Address,
|
|||
|
RPC_STATUS * pStatus
|
|||
|
);
|
|||
|
|
|||
|
~DG_SCONNECTION();
|
|||
|
|
|||
|
virtual RPC_STATUS
|
|||
|
SealAndSendPacket(
|
|||
|
IN DG_ENDPOINT * SourceEndpoint,
|
|||
|
IN DG_TRANSPORT_ADDRESS RemoteAddress,
|
|||
|
IN UNALIGNED NCA_PACKET_HEADER * Header,
|
|||
|
IN unsigned long DataOffset
|
|||
|
);
|
|||
|
|
|||
|
void
|
|||
|
Activate(
|
|||
|
PNCA_PACKET_HEADER pHeader,
|
|||
|
unsigned short NewHash
|
|||
|
);
|
|||
|
|
|||
|
void Deactivate();
|
|||
|
|
|||
|
PDG_SCALL AllocateCall();
|
|||
|
|
|||
|
void
|
|||
|
FreeCall(
|
|||
|
PDG_SCALL Call
|
|||
|
);
|
|||
|
|
|||
|
void CheckForExpiredCalls();
|
|||
|
|
|||
|
inline BOOL HasExpired();
|
|||
|
|
|||
|
inline void
|
|||
|
DispatchPacket(
|
|||
|
DG_PACKET * Packet,
|
|||
|
DatagramTransportPair *AddressPair
|
|||
|
);
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
MakeApplicationSecurityCallback(
|
|||
|
RPC_INTERFACE * Interface,
|
|||
|
PDG_SCALL Call
|
|||
|
);
|
|||
|
|
|||
|
inline void
|
|||
|
AddCallToCache(
|
|||
|
DG_SCALL * Call
|
|||
|
);
|
|||
|
|
|||
|
inline LONG
|
|||
|
IncrementRefCount(
|
|||
|
)
|
|||
|
{
|
|||
|
ASSERT(ReferenceCount < 1000);
|
|||
|
return InterlockedIncrement(&ReferenceCount);
|
|||
|
}
|
|||
|
|
|||
|
inline LONG
|
|||
|
DecrementRefCount(
|
|||
|
)
|
|||
|
{
|
|||
|
ASSERT(ReferenceCount > 0);
|
|||
|
return InterlockedDecrement(&ReferenceCount);
|
|||
|
}
|
|||
|
|
|||
|
inline static DG_SCONNECTION *
|
|||
|
FromHashNode(
|
|||
|
UUID_HASH_TABLE_NODE * Node
|
|||
|
)
|
|||
|
{
|
|||
|
return CONTAINING_RECORD (Node, DG_SCONNECTION, ActivityNode);
|
|||
|
}
|
|||
|
|
|||
|
inline LONG GetTimeStamp()
|
|||
|
{
|
|||
|
return TimeStamp;
|
|||
|
}
|
|||
|
|
|||
|
inline BOOL DidCallbackFail()
|
|||
|
{
|
|||
|
if (Callback.State == CallbackFailed)
|
|||
|
{
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
VerifyNonRequestPacket(
|
|||
|
DG_PACKET * Packet
|
|||
|
);
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
VerifyRequestPacket(
|
|||
|
DG_PACKET * Packet
|
|||
|
);
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
FindOrCreateSecurityContext(
|
|||
|
IN DG_PACKET * pPacket,
|
|||
|
IN DG_TRANSPORT_ADDRESS RemoteAddress,
|
|||
|
OUT unsigned long * pClientSequenceNumber
|
|||
|
);
|
|||
|
|
|||
|
inline SECURITY_CONTEXT *
|
|||
|
FindMatchingSecurityContext(
|
|||
|
DG_PACKET * Packet
|
|||
|
);
|
|||
|
|
|||
|
inline DG_SCALL *
|
|||
|
RemoveIdleCalls(
|
|||
|
DG_SCALL * List,
|
|||
|
BOOL Aggressive,
|
|||
|
RPC_INTERFACE * Interface
|
|||
|
);
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
GetAssociationGroup(
|
|||
|
DG_TRANSPORT_ADDRESS RemoteAddress
|
|||
|
);
|
|||
|
|
|||
|
inline void
|
|||
|
SubmitCallbackIfNecessary(
|
|||
|
PDG_SCALL Call,
|
|||
|
PDG_PACKET Packet,
|
|||
|
DG_TRANSPORT_ADDRESS RemoteAddress
|
|||
|
);
|
|||
|
|
|||
|
void ConvCallCompleted();
|
|||
|
|
|||
|
inline void MessageMutexInitialize( RPC_STATUS *pStatus )
|
|||
|
{
|
|||
|
pMessageMutex = new MUTEX3(pStatus);
|
|||
|
|
|||
|
if (!pMessageMutex)
|
|||
|
{
|
|||
|
*pStatus = RPC_S_OUT_OF_MEMORY;
|
|||
|
}
|
|||
|
else if (*pStatus != RPC_S_OK)
|
|||
|
{
|
|||
|
delete pMessageMutex;
|
|||
|
pMessageMutex = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private:
|
|||
|
|
|||
|
DG_SCALL * CachedCalls;
|
|||
|
|
|||
|
DG_SCALL_TABLE ActiveCalls;
|
|||
|
|
|||
|
SECURITY_CONTEXT_DICT2 SecurityContextDict;
|
|||
|
|
|||
|
unsigned MaxKeySeq;
|
|||
|
|
|||
|
SECURITY_CALLBACK_INFO_DICT2 InterfaceCallbackResults;
|
|||
|
|
|||
|
struct
|
|||
|
{
|
|||
|
CALLBACK_STATE State;
|
|||
|
|
|||
|
RPC_BINDING_HANDLE Binding;
|
|||
|
RPC_ASYNC_STATE AsyncState;
|
|||
|
|
|||
|
DG_SCALL * Call;
|
|||
|
SECURITY_CREDENTIALS * Credentials;
|
|||
|
SECURITY_CONTEXT * SecurityContext;
|
|||
|
BOOL ThirdLegNeeded;
|
|||
|
DWORD DataRep;
|
|||
|
DWORD KeySequence;
|
|||
|
|
|||
|
RPC_UUID CasUuid;
|
|||
|
unsigned long ClientSequence;
|
|||
|
unsigned char * TokenBuffer;
|
|||
|
long TokenLength;
|
|||
|
unsigned char * ResponseBuffer;
|
|||
|
long ResponseLength;
|
|||
|
long MaxData;
|
|||
|
unsigned long DataIndex;
|
|||
|
unsigned long Status;
|
|||
|
}
|
|||
|
Callback;
|
|||
|
|
|||
|
boolean BlockIdleCallRemoval;
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
|
|||
|
void CallDispatchLoop();
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
FinishConvCallback(
|
|||
|
RPC_STATUS Status
|
|||
|
);
|
|||
|
|
|||
|
BOOL
|
|||
|
HandleMaybeCall(
|
|||
|
PDG_PACKET Packet,
|
|||
|
DatagramTransportPair *AddressPair
|
|||
|
);
|
|||
|
|
|||
|
PDG_SCALL
|
|||
|
HandleNewCall(
|
|||
|
PDG_PACKET Packet,
|
|||
|
DatagramTransportPair *AddressPair
|
|||
|
);
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
CreateCallbackBindingAndReleaseMutex(
|
|||
|
DG_TRANSPORT_ADDRESS RemoteAddress
|
|||
|
);
|
|||
|
|
|||
|
static void RPC_ENTRY
|
|||
|
ConvNotificationRoutine (
|
|||
|
RPC_ASYNC_STATE * pAsync,
|
|||
|
void * Reserved,
|
|||
|
RPC_ASYNC_EVENT Event
|
|||
|
);
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
inline SECURITY_CONTEXT *
|
|||
|
DG_SCONNECTION::FindMatchingSecurityContext(
|
|||
|
DG_PACKET * Packet
|
|||
|
)
|
|||
|
{
|
|||
|
DG_SECURITY_TRAILER * Verifier = (DG_SECURITY_TRAILER *)
|
|||
|
(Packet->Header.Data + Packet->GetPacketBodyLen());
|
|||
|
|
|||
|
return SecurityContextDict.Find(Verifier->key_vers_num);
|
|||
|
}
|
|||
|
|
|||
|
class DG_SCALL : public SCALL, public DG_PACKET_ENGINE
|
|||
|
/*++
|
|||
|
|
|||
|
Class Description:
|
|||
|
|
|||
|
This class represents a call in progress on the server.
|
|||
|
|
|||
|
Fields:
|
|||
|
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
#ifdef MONITOR_SERVER_PACKET_COUNT
|
|||
|
long OutstandingPacketCount;
|
|||
|
#endif
|
|||
|
|
|||
|
public:
|
|||
|
|
|||
|
long TimeStamp;
|
|||
|
DG_SCALL * Next;
|
|||
|
DG_SCALL * Previous;
|
|||
|
|
|||
|
//------------------------------------------------
|
|||
|
|
|||
|
|
|||
|
inline void *
|
|||
|
operator new(
|
|||
|
IN size_t ObjectLength,
|
|||
|
IN RPC_DATAGRAM_TRANSPORT * TransportInterface
|
|||
|
);
|
|||
|
|
|||
|
DG_SCALL(
|
|||
|
DG_ADDRESS * Address,
|
|||
|
RPC_STATUS * pStatus
|
|||
|
);
|
|||
|
|
|||
|
virtual ~DG_SCALL();
|
|||
|
|
|||
|
//------------------------------------------------
|
|||
|
|
|||
|
virtual RPC_STATUS
|
|||
|
NegotiateTransferSyntax (
|
|||
|
IN OUT PRPC_MESSAGE Message
|
|||
|
);
|
|||
|
|
|||
|
virtual RPC_STATUS
|
|||
|
GetBuffer (
|
|||
|
IN OUT PRPC_MESSAGE Message,
|
|||
|
IN UUID *ObjectUuid
|
|||
|
);
|
|||
|
|
|||
|
virtual void
|
|||
|
FreeBuffer (
|
|||
|
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
|
|||
|
SendReceive (
|
|||
|
IN OUT PRPC_MESSAGE Message
|
|||
|
);
|
|||
|
|
|||
|
virtual RPC_STATUS
|
|||
|
ToStringBinding (
|
|||
|
OUT RPC_CHAR PAPI * PAPI * StringBinding
|
|||
|
);
|
|||
|
|
|||
|
virtual RPC_STATUS
|
|||
|
ImpersonateClient (
|
|||
|
);
|
|||
|
|
|||
|
virtual RPC_STATUS
|
|||
|
RevertToSelf (
|
|||
|
);
|
|||
|
|
|||
|
virtual RPC_STATUS
|
|||
|
GetAssociationContextCollection (
|
|||
|
OUT ContextCollection **CtxCollection
|
|||
|
);
|
|||
|
|
|||
|
virtual void
|
|||
|
InquireObjectUuid (
|
|||
|
OUT RPC_UUID PAPI * ObjectUuid
|
|||
|
);
|
|||
|
|
|||
|
virtual RPC_STATUS
|
|||
|
InquireAuthClient (
|
|||
|
OUT RPC_AUTHZ_HANDLE PAPI * Privileges,
|
|||
|
OUT RPC_CHAR PAPI * PAPI * ServerPrincipalName, OPTIONAL
|
|||
|
OUT unsigned long PAPI * AuthenticationLevel,
|
|||
|
OUT unsigned long PAPI * AuthenticationService,
|
|||
|
OUT unsigned long PAPI * AuthorizationService,
|
|||
|
IN unsigned long Flags
|
|||
|
);
|
|||
|
|
|||
|
virtual RPC_STATUS
|
|||
|
ConvertToServerBinding (
|
|||
|
OUT RPC_BINDING_HANDLE __RPC_FAR * ServerBinding
|
|||
|
);
|
|||
|
|
|||
|
virtual RPC_STATUS
|
|||
|
InqTransportType(
|
|||
|
OUT unsigned int __RPC_FAR * Type
|
|||
|
) ;
|
|||
|
|
|||
|
virtual RPC_STATUS
|
|||
|
Cancel(
|
|||
|
void * ThreadHandle
|
|||
|
);
|
|||
|
|
|||
|
virtual unsigned TestCancel();
|
|||
|
|
|||
|
virtual RPC_STATUS
|
|||
|
Receive(
|
|||
|
PRPC_MESSAGE Message,
|
|||
|
unsigned Size
|
|||
|
);
|
|||
|
|
|||
|
virtual RPC_STATUS
|
|||
|
Send(
|
|||
|
PRPC_MESSAGE Message
|
|||
|
);
|
|||
|
|
|||
|
virtual RPC_STATUS
|
|||
|
AsyncSend (
|
|||
|
IN OUT PRPC_MESSAGE Message
|
|||
|
);
|
|||
|
|
|||
|
virtual RPC_STATUS
|
|||
|
AsyncReceive (
|
|||
|
IN OUT PRPC_MESSAGE Message,
|
|||
|
IN unsigned int Size
|
|||
|
);
|
|||
|
|
|||
|
virtual RPC_STATUS
|
|||
|
IsClientLocal(
|
|||
|
IN OUT unsigned * pClientIsLocal
|
|||
|
)
|
|||
|
{
|
|||
|
return RPC_S_CANNOT_SUPPORT;
|
|||
|
}
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
InqLocalConnAddress (
|
|||
|
IN OUT void *Buffer,
|
|||
|
IN OUT unsigned long *BufferSize,
|
|||
|
OUT unsigned long *AddressFormat
|
|||
|
);
|
|||
|
|
|||
|
virtual RPC_STATUS
|
|||
|
AbortAsyncCall (
|
|||
|
IN PRPC_ASYNC_STATE pAsync,
|
|||
|
IN unsigned long ExceptionCode
|
|||
|
);
|
|||
|
|
|||
|
virtual RPC_STATUS
|
|||
|
SetAsyncHandle (
|
|||
|
IN RPC_ASYNC_STATE * pAsync
|
|||
|
);
|
|||
|
|
|||
|
virtual BOOL
|
|||
|
IsSyncCall ()
|
|||
|
{
|
|||
|
return !pAsync;
|
|||
|
}
|
|||
|
|
|||
|
//------------------------------------------------
|
|||
|
|
|||
|
inline void
|
|||
|
DispatchPacket(
|
|||
|
DG_PACKET * Packet,
|
|||
|
IN DG_TRANSPORT_ADDRESS RemoteAddress
|
|||
|
);
|
|||
|
|
|||
|
void DealWithRequest ( PDG_PACKET pPacket );
|
|||
|
void DealWithResponse ( PDG_PACKET pPacket );
|
|||
|
void DealWithPing ( PDG_PACKET pPacket );
|
|||
|
void DealWithFack ( PDG_PACKET pPacket );
|
|||
|
void DealWithAck ( PDG_PACKET pPacket );
|
|||
|
void DealWithQuit ( PDG_PACKET pPacket );
|
|||
|
|
|||
|
//------------------------------------------------
|
|||
|
|
|||
|
inline void
|
|||
|
NewCall(
|
|||
|
DG_PACKET * pPacket,
|
|||
|
DatagramTransportPair *AddressPAir
|
|||
|
);
|
|||
|
|
|||
|
inline void
|
|||
|
BindToConnection(
|
|||
|
PDG_SCONNECTION a_Connection
|
|||
|
);
|
|||
|
|
|||
|
BOOL
|
|||
|
DG_SCALL::FinishSendOrReceive(
|
|||
|
BOOL Abort
|
|||
|
);
|
|||
|
|
|||
|
inline BOOL ReadyToDispatch();
|
|||
|
|
|||
|
void ProcessRpcCall();
|
|||
|
|
|||
|
inline BOOL
|
|||
|
HasExpired(
|
|||
|
BOOL Aggressive,
|
|||
|
RPC_INTERFACE * Interface
|
|||
|
);
|
|||
|
|
|||
|
BOOL Cleanup();
|
|||
|
|
|||
|
inline BOOL IsSynchronous();
|
|||
|
|
|||
|
void
|
|||
|
FreeAPCInfo (
|
|||
|
IN RPC_APC_INFO *pAPCInfo
|
|||
|
);
|
|||
|
|
|||
|
inline void IncrementRefCount();
|
|||
|
inline void DecrementRefCount();
|
|||
|
|
|||
|
inline void
|
|||
|
ConvCallbackFailed(
|
|||
|
DWORD Status
|
|||
|
)
|
|||
|
{
|
|||
|
pSavedPacket->Header.SequenceNumber = SequenceNumber;
|
|||
|
|
|||
|
InitErrorPacket(pSavedPacket, DG_REJECT, Status);
|
|||
|
SealAndSendPacket(&pSavedPacket->Header);
|
|||
|
Cleanup();
|
|||
|
}
|
|||
|
|
|||
|
virtual RPC_STATUS
|
|||
|
InqConnection (
|
|||
|
OUT void **ConnId,
|
|||
|
OUT BOOL *pfFirstCall
|
|||
|
)
|
|||
|
{
|
|||
|
ASSERT(Connection);
|
|||
|
*ConnId = Connection;
|
|||
|
|
|||
|
if (InterlockedIncrement((LONG *) &(Connection->fFirstCall)) == 1)
|
|||
|
{
|
|||
|
*pfFirstCall = 1;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
*pfFirstCall = 0;
|
|||
|
}
|
|||
|
|
|||
|
return RPC_S_OK;
|
|||
|
}
|
|||
|
|
|||
|
private:
|
|||
|
|
|||
|
enum CALL_STATE
|
|||
|
{
|
|||
|
CallInit = 0x201,
|
|||
|
CallBeforeDispatch,
|
|||
|
CallDispatched,
|
|||
|
xxxxObsolete,
|
|||
|
CallAfterDispatch,
|
|||
|
CallSendingResponse,
|
|||
|
CallComplete,
|
|||
|
CallBogus = 0xfffff004
|
|||
|
};
|
|||
|
|
|||
|
CALL_STATE State;
|
|||
|
CALL_STATE PreviousState;
|
|||
|
|
|||
|
boolean CallInProgress;
|
|||
|
boolean CallWasForwarded;
|
|||
|
boolean KnowClientAddress;
|
|||
|
boolean TerminateWhenConvenient;
|
|||
|
|
|||
|
DG_SCONNECTION * Connection;
|
|||
|
RPC_INTERFACE * Interface;
|
|||
|
|
|||
|
//
|
|||
|
// Data to monitor pipe data transfer.
|
|||
|
//
|
|||
|
unsigned long PipeThreadId;
|
|||
|
|
|||
|
PENDING_OPERATION PipeWaitType;
|
|||
|
unsigned long PipeWaitLength;
|
|||
|
|
|||
|
//
|
|||
|
// The only unusual aspect of this is that it's an auto-reset event.
|
|||
|
// It is created during the first call on a pipe interface.
|
|||
|
//
|
|||
|
EVENT * PipeWaitEvent;
|
|||
|
|
|||
|
//
|
|||
|
// Stuff for RpcBindingInqAuthClient.
|
|||
|
//
|
|||
|
RPC_AUTHZ_HANDLE Privileges;
|
|||
|
unsigned long AuthorizationService;
|
|||
|
|
|||
|
DWORD LocalAddress; // IP address, network byte order encoded
|
|||
|
|
|||
|
//---------------------------------------------------------------------
|
|||
|
|
|||
|
inline void
|
|||
|
SetState(
|
|||
|
CALL_STATE NewState
|
|||
|
)
|
|||
|
{
|
|||
|
if (NewState != State)
|
|||
|
{
|
|||
|
LogEvent(SU_SCALL, EV_STATE, this, 0, NewState);
|
|||
|
}
|
|||
|
|
|||
|
PreviousState = State;
|
|||
|
State = NewState;
|
|||
|
}
|
|||
|
|
|||
|
virtual BOOL
|
|||
|
IssueNotification (
|
|||
|
IN RPC_ASYNC_EVENT Event
|
|||
|
);
|
|||
|
|
|||
|
void
|
|||
|
AddPacketToReceiveList(
|
|||
|
PDG_PACKET pPacket
|
|||
|
);
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
UnauthenticatedCallback(
|
|||
|
unsigned * pClientSequenceNumber
|
|||
|
);
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
SendFragment(
|
|||
|
PRPC_MESSAGE pMessage,
|
|||
|
unsigned FragNum,
|
|||
|
unsigned char PacketType
|
|||
|
);
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
SealAndSendPacket(
|
|||
|
NCA_PACKET_HEADER * Header
|
|||
|
);
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
SendPacketBack(
|
|||
|
NCA_PACKET_HEADER * pNcaPacketHeader,
|
|||
|
unsigned TrailerSize
|
|||
|
);
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
CreateReverseBinding (
|
|||
|
RPC_BINDING_HANDLE * pServerBinding,
|
|||
|
BOOL IncludeEndpoint
|
|||
|
);
|
|||
|
|
|||
|
void
|
|||
|
SaveOriginalClientInfo(
|
|||
|
DG_PACKET * pPacket
|
|||
|
);
|
|||
|
|
|||
|
inline RPC_STATUS
|
|||
|
AssembleBufferFromPackets(
|
|||
|
IN OUT PRPC_MESSAGE Message
|
|||
|
);
|
|||
|
|
|||
|
RPC_STATUS WaitForPipeEvent();
|
|||
|
|
|||
|
//------------------------------------------------
|
|||
|
// ConvertSidToUserW() is used to get transport supplied
|
|||
|
// auth. info. The only DG transport that uses this is
|
|||
|
// Falcon. The SID for the client user that sent the
|
|||
|
// "current" request is cashed along with the user name.
|
|||
|
// So, if the next call on this activity has the same
|
|||
|
// SID we can return the user without hitting the domain
|
|||
|
// server.
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
ConvertSidToUserW(
|
|||
|
IN SID *pSid,
|
|||
|
OUT RPC_CHAR **ppwsPrincipal
|
|||
|
);
|
|||
|
|
|||
|
SID *pCachedSid;
|
|||
|
RPC_CHAR *pwsCachedUserName;
|
|||
|
DWORD dwCachedUserNameSize;
|
|||
|
|
|||
|
boolean FinalSendBufferPresent;
|
|||
|
|
|||
|
RPC_MESSAGE RpcMessage;
|
|||
|
RPC_RUNTIME_INFO RpcRuntimeInfo ;
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
inline void *
|
|||
|
DG_SCALL::operator new(
|
|||
|
IN size_t ObjectLength,
|
|||
|
IN RPC_DATAGRAM_TRANSPORT * TransportInterface
|
|||
|
)
|
|||
|
{
|
|||
|
return new char[ObjectLength + TransportInterface->AddressSize];
|
|||
|
}
|
|||
|
|
|||
|
inline void DG_SCALL::DecrementRefCount()
|
|||
|
{
|
|||
|
Connection->Mutex.VerifyOwned();
|
|||
|
|
|||
|
--ReferenceCount;
|
|||
|
|
|||
|
LogEvent(SU_SCALL, EV_DEC, this, 0, ReferenceCount);
|
|||
|
}
|
|||
|
|
|||
|
inline void DG_SCALL::IncrementRefCount()
|
|||
|
{
|
|||
|
Connection->Mutex.VerifyOwned();
|
|||
|
|
|||
|
++ReferenceCount;
|
|||
|
|
|||
|
LogEvent(SU_SCALL, EV_INC, this, 0, ReferenceCount);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void
|
|||
|
DG_SCALL::BindToConnection(
|
|||
|
PDG_SCONNECTION a_Connection
|
|||
|
)
|
|||
|
{
|
|||
|
Connection = a_Connection;
|
|||
|
|
|||
|
ReadConnectionInfo(Connection, this + 1);
|
|||
|
|
|||
|
pSavedPacket->Header.ServerBootTime = ProcessStartTime;
|
|||
|
pSavedPacket->Header.ActivityHint = (unsigned short) Connection->ActivityHint;
|
|||
|
pSavedPacket->Header.InterfaceHint = 0xffff;
|
|||
|
}
|
|||
|
|
|||
|
inline BOOL
|
|||
|
DG_SCALL::IsSynchronous(
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Simply tells whether the call is sycnhronous or asynchronous.
|
|||
|
|
|||
|
The return value won't be reliable if the call was instantiated
|
|||
|
by a packet other than a REQUEST and no REQUEST has yet arrived,
|
|||
|
so be careful to call it only after a REQUEST has arrived.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
none
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE if synchronous
|
|||
|
FALSE if asynchronous
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
if (BufferFlags & RPC_BUFFER_ASYNC)
|
|||
|
{
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
inline RPC_STATUS
|
|||
|
DG_SCALL::AssembleBufferFromPackets(
|
|||
|
IN OUT PRPC_MESSAGE Message
|
|||
|
)
|
|||
|
{
|
|||
|
RPC_STATUS Status = DG_PACKET_ENGINE::AssembleBufferFromPackets(Message, this);
|
|||
|
|
|||
|
if (RPC_S_OK == Status && (Message->RpcFlags & RPC_BUFFER_EXTRA))
|
|||
|
{
|
|||
|
PRPC_RUNTIME_INFO Info = (PRPC_RUNTIME_INFO) Message->ReservedForRuntime;
|
|||
|
|
|||
|
Info->OldBuffer = Message->Buffer;
|
|||
|
}
|
|||
|
|
|||
|
return Status;
|
|||
|
}
|
|||
|
|
|||
|
inline RPC_STATUS
|
|||
|
DG_SCALL::InqTransportType(
|
|||
|
OUT unsigned int __RPC_FAR * Type
|
|||
|
)
|
|||
|
{
|
|||
|
*Type = TRANSPORT_TYPE_DG ;
|
|||
|
|
|||
|
return (RPC_S_OK) ;
|
|||
|
}
|
|||
|
|
|||
|
inline RPC_STATUS
|
|||
|
DG_SCALL::SealAndSendPacket(
|
|||
|
NCA_PACKET_HEADER * Header
|
|||
|
)
|
|||
|
{
|
|||
|
Header->ServerBootTime = ProcessStartTime;
|
|||
|
SetMyDataRep(Header);
|
|||
|
|
|||
|
unsigned Frag = (Header->PacketType << 16) | Header->FragmentNumber;
|
|||
|
LogEvent(SU_SCALL, EV_PKT_OUT, this, 0, Frag);
|
|||
|
|
|||
|
return Connection->SealAndSendPacket(SourceEndpoint, RemoteAddress, Header, 0);
|
|||
|
}
|
|||
|
|
|||
|
//------------------------------------------------------------------------
|
|||
|
|
|||
|
|
|||
|
class SERVER_ACTIVITY_TABLE : private UUID_HASH_TABLE
|
|||
|
{
|
|||
|
public:
|
|||
|
|
|||
|
inline
|
|||
|
SERVER_ACTIVITY_TABLE(
|
|||
|
RPC_STATUS * pStatus
|
|||
|
) :
|
|||
|
UUID_HASH_TABLE ( pStatus )
|
|||
|
{
|
|||
|
LastFinishTime = 0;
|
|||
|
BucketCounter = 0;
|
|||
|
}
|
|||
|
|
|||
|
inline
|
|||
|
~SERVER_ACTIVITY_TABLE(
|
|||
|
)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
inline DG_SCONNECTION *
|
|||
|
FindOrCreate(
|
|||
|
DG_ADDRESS * Address,
|
|||
|
PDG_PACKET pPacket
|
|||
|
);
|
|||
|
|
|||
|
inline void Prune();
|
|||
|
|
|||
|
BOOL
|
|||
|
PruneEntireTable(
|
|||
|
RPC_INTERFACE * Interface
|
|||
|
);
|
|||
|
|
|||
|
BOOL PruneSpecificBucket(
|
|||
|
unsigned Bucket,
|
|||
|
BOOL Aggressive,
|
|||
|
RPC_INTERFACE * Interface
|
|||
|
);
|
|||
|
|
|||
|
void SERVER_ACTIVITY_TABLE::BeginIdlePruning();
|
|||
|
|
|||
|
static void SERVER_ACTIVITY_TABLE::PruneWhileIdle( PVOID unused );
|
|||
|
|
|||
|
private:
|
|||
|
|
|||
|
long LastFinishTime;
|
|||
|
long BucketCounter;
|
|||
|
|
|||
|
DELAYED_ACTION_NODE IdleScavengerTimer;
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
class ASSOC_GROUP_TABLE : private UUID_HASH_TABLE
|
|||
|
{
|
|||
|
public:
|
|||
|
|
|||
|
inline
|
|||
|
ASSOC_GROUP_TABLE(
|
|||
|
RPC_STATUS * pStatus
|
|||
|
)
|
|||
|
: UUID_HASH_TABLE(pStatus)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
inline
|
|||
|
~ASSOC_GROUP_TABLE(
|
|||
|
)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
inline ASSOCIATION_GROUP *
|
|||
|
FindOrCreate(
|
|||
|
RPC_UUID * pUuid,
|
|||
|
unsigned short InitialPduSize
|
|||
|
);
|
|||
|
|
|||
|
inline void
|
|||
|
DecrementRefCount(
|
|||
|
ASSOCIATION_GROUP * pClient
|
|||
|
);
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
inline void
|
|||
|
DG_SCONNECTION::AddCallToCache(
|
|||
|
DG_SCALL * Call
|
|||
|
)
|
|||
|
{
|
|||
|
Mutex.VerifyOwned();
|
|||
|
|
|||
|
ASSERT( !Call->InvalidHandle(DG_SCALL_TYPE) );
|
|||
|
ASSERT( !CachedCalls || !CachedCalls->InvalidHandle(DG_SCALL_TYPE) );
|
|||
|
|
|||
|
Call->TimeStamp = GetTickCount();
|
|||
|
Call->Next = CachedCalls;
|
|||
|
CachedCalls = Call;
|
|||
|
|
|||
|
LogEvent(SU_SCALL, EV_STOP, Call, this, Call->GetSequenceNumber() );
|
|||
|
}
|
|||
|
|
|||
|
//------------------------------------------------------------------------
|
|||
|
|
|||
|
BOOL
|
|||
|
StripForwardedPacket(
|
|||
|
IN PDG_PACKET pPacket,
|
|||
|
IN void * pFromEndpoint
|
|||
|
);
|
|||
|
|
|||
|
extern unsigned long ServerBootTime;
|
|||
|
|
|||
|
|
|||
|
#endif // __DGSVR_HXX__
|
|||
|
|
|||
|
|