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.
 
 
 
 
 
 

336 lines
8.3 KiB

/**********************************************************************/
/** Microsoft Windows NT **/
/** Copyright(c) Microsoft Corp., 1994 **/
/**********************************************************************/
/*
conn.hxx
This module contains the connection class
FILE HISTORY:
Johnl 15-Aug-1994 Created
*/
#ifndef _CONN_HXX_
#define _CONN_HXX_
//
// The default timeout to wait for the completion of an Atq IO request (in sec)
//
#define W3_IO_TIMEOUT (5*60)
//
// The initial size of the buffer to receive the client request
//
#define W3_DEFAULT_BUFFSIZE 4096
//
// The end of a line is considered to be the linefeed character
//
#define W3_EOL 0x0A
//
// Valid signature of a CLIENT_CONN_STATE
//
#define CLIENT_CONN_SIGNATURE 0x51204343 // 'CCS '
//
// Invalid signature of a CLIENT_CONN_STATE
//
#define CLIENT_CONN_SIGNATURE_FREE 0x43514743 // 'FCCS'
//
// The various states a CLIENT_CONN object can be in
//
enum CLIENT_CONN_STATE
{
//
// We've just accepted the TCP connection from the client but we have
// no other information.
//
CCS_STARTUP = 0,
//
// We are in the process of receiving the client's HTTP request buffer
//
CCS_GETTING_CLIENT_REQ,
//
// We are reading data from the client socket meant for a gateway
//
CCS_GATHERING_GATEWAY_DATA,
//
// We're executing the clients HTTP request
//
CCS_PROCESSING_CLIENT_REQ,
//
// The server or client has initiated a disconnect. We have to
// wait till all outstanding IO requests are completed before
// cleaning up
//
CCS_DISCONNECTING,
//
// All pending requests have been completed. Finish cleaning
// up.
//
CCS_SHUTDOWN
};
class CLIENT_CONN
{
public:
BOOL IsValid( VOID )
{ return _fIsValid; }
//
// This is the work entry point that is driven by the completion of the
// async IO.
//
BOOL DoWork( DWORD BytesWritten,
DWORD CompletionStatus,
BOOL fIOCompletion);
//
// Optionally sends a status response then initiates the disconnect
//
// HTResponse - HTTP status code
// ErrorResponse - System error or resource ID of response
//
// If this function fails, then the connection will be aborted
//
VOID Disconnect( HTTP_REQ_BASE * pRequest = NULL,
DWORD HTResponse = 0,
DWORD ErrorResponse = NO_ERROR,
BOOL fDoShutdown = TRUE );
BOOL OnSessionStartup( PVOID pvInitial = NULL,
DWORD cbInitial = 0 );
//
// Walks the connection list and calls disconnect on each connection
//
static VOID DisconnectAllUsers( VOID );
//
// Increments and decrements the reference count
//
UINT Reference( VOID )
{ return ::InterlockedIncrement( &_cRef ); }
UINT Dereference( VOID )
{ return ::InterlockedDecrement( &_cRef ); }
UINT QueryRefCount( VOID ) const
{ return _cRef; }
//
// Simple wrappers to the corresponding Atq functions
//
BOOL ReadFile( LPVOID lpBuffer,
DWORD nBytesToRead );
BOOL WriteFile( LPVOID lpBuffer,
DWORD nBytesToRead );
BOOL TransmitFile( HANDLE hFile,
DWORD BytesToWrite,
DWORD dwFlags,
PVOID pHead = NULL,
DWORD HeadLength = 0,
PVOID pTail = NULL,
DWORD TailLength = 0 );
BOOL TransmitFileEx( HANDLE hFile,
DWORD Offset,
DWORD BytesToWrite,
DWORD dwFlags,
PVOID pHead = NULL,
DWORD HeadLength = 0,
PVOID pTail = NULL,
DWORD TailLength = 0 );
BOOL PostCompletionStatus( DWORD BytesTransferred );
//
// This list entry is put on the client connection list
//
LIST_ENTRY ListEntry;
SOCKET QuerySocket( VOID ) const
{ return _sClient; }
PATQ_CONTEXT QueryAtqContext( VOID ) const
{ return _AtqContext; }
USHORT QueryPort( VOID ) const
{ return _sPort; }
BOOL IsSecurePort( VOID ) const
{ return _sPort == SecurePort; }
//
// Make sure the next state is set before an async IO call is made
//
enum CLIENT_CONN_STATE QueryState( VOID ) const
{ return _ccState; }
VOID SetState( CLIENT_CONN_STATE ccState )
{ _ccState = ccState; }
BOOL CheckSignature( VOID ) const
{ return _Signature == CLIENT_CONN_SIGNATURE; }
TCHAR * QueryRemoteAddr( VOID ) const
{ return (TCHAR *) _achRemoteAddr; }
TCHAR * QueryLocalAddr( VOID ) const
{ return (TCHAR *) _achLocalAddr; }
VOID SetAtqReuseContextFlag( BOOL fReuseContext )
{ _fReuseContext = fReuseContext; }
static DWORD Initialize( VOID );
static VOID Terminate( VOID );
static CLIENT_CONN * Alloc( SOCKET sClient,
SOCKADDR_IN * psockaddrLocal,
SOCKADDR_IN * psockaddrRemote,
PATQ_CONTEXT patqContext,
PVOID pvInitialBuff,
DWORD cbInitialBuff );
static VOID Free( CLIENT_CONN * pConn );
protected:
//
// Constructor and destructor
//
CLIENT_CONN( SOCKET sClient,
SOCKADDR_IN * psockaddrLocal,
SOCKADDR_IN * psockaddrRemote,
PATQ_CONTEXT patqContext,
PVOID pvInitialBuff,
DWORD cbInitialBuff );
VOID Initialize( SOCKET sClient,
SOCKADDR_IN * psockaddrLocal,
SOCKADDR_IN * psockaddrRemote,
PATQ_CONTEXT patqContext,
PVOID pvInitialBuff,
DWORD cbInitialBuff );
~CLIENT_CONN( VOID );
VOID Reset( VOID );
BOOL IsCleaningUp( VOID ) const
{ return QueryState() == CCS_DISCONNECTING ||
QueryState() == CCS_SHUTDOWN;
}
private:
//
// Contains the CLIENT_CONN signature
//
ULONG _Signature;
//
// Construction success indicator
//
BOOL _fIsValid;
//
// Contains the client socket connection openned by the connection thread
//
SOCKET _sClient;
enum CLIENT_CONN_STATE _ccState;
//
// Reference count. Can't go away until the count reaches 0
//
LONG _cRef;
//
// Contains an ASCII representation of the client's remote address
// and the adapter local address
//
TCHAR _achRemoteAddr[25];
TCHAR _achLocalAddr[25];
//
// Port this connection is on
//
USHORT _sPort;
//
// Parses the data and determines the appropriate action
//
HTTP_REQ_BASE * _phttpReq;
//
// Initial receive buffer if we're doing AcceptEx processing
//
PVOID _pvInitial;
DWORD _cbInitial;
PATQ_CONTEXT _AtqContext;
//
// If FALSE, the Atq Context should not be reused because the calling
// thread will be exiting soon
//
BOOL _fReuseContext;
//
// Response string for disconnect notifications.
//
// NOTE: If the server handles non-serial requests, then two request completing at
// the same time could use this string
//
STR _strResponse;
//
// These are for the lookaside buffer list
//
static CRITICAL_SECTION _csBuffList;
static LIST_ENTRY _BuffListHead;
static BOOL _fGlobalInit;
LIST_ENTRY _BuffListEntry;
};
//
// Functions for connection reference counts
//
inline VOID ReferenceConn( CLIENT_CONN * pConn )
{
pConn->Reference();
}
inline VOID DereferenceConn( CLIENT_CONN * pConn )
{
if ( !pConn->Dereference() )
CLIENT_CONN::Free( pConn );
}
#endif // !_CONN_HXX_