489 lines
9.9 KiB
C++
489 lines
9.9 KiB
C++
|
#ifndef _RAWCONNECTION_HXX_
|
||
|
#define _RAWCONNECTION_HXX_
|
||
|
|
||
|
#include <streamfilt.h>
|
||
|
#include "w3filter.hxx"
|
||
|
|
||
|
#define RAW_CONNECTION_SIGNATURE (DWORD)'NOCR'
|
||
|
#define RAW_CONNECTION_SIGNATURE_FREE (DWORD)'nocr'
|
||
|
|
||
|
class RAW_CONNECTION_HASH;
|
||
|
|
||
|
class W3_CONNECTION;
|
||
|
|
||
|
class RAW_CONNECTION
|
||
|
{
|
||
|
public:
|
||
|
RAW_CONNECTION(
|
||
|
CONNECTION_INFO * pConnectionInfo
|
||
|
);
|
||
|
|
||
|
virtual ~RAW_CONNECTION();
|
||
|
|
||
|
static
|
||
|
HRESULT
|
||
|
Initialize(
|
||
|
VOID
|
||
|
);
|
||
|
|
||
|
static
|
||
|
VOID
|
||
|
Terminate(
|
||
|
VOID
|
||
|
);
|
||
|
|
||
|
static
|
||
|
HRESULT
|
||
|
StartListening(
|
||
|
VOID
|
||
|
);
|
||
|
|
||
|
static
|
||
|
HRESULT
|
||
|
StopListening(
|
||
|
VOID
|
||
|
);
|
||
|
|
||
|
static
|
||
|
HRESULT
|
||
|
GetConnection(
|
||
|
CONNECTION_INFO * pConnectionInfo,
|
||
|
RAW_CONNECTION ** ppRawConnection
|
||
|
);
|
||
|
|
||
|
static
|
||
|
HRESULT
|
||
|
FindConnection(
|
||
|
HTTP_RAW_CONNECTION_ID ConnectionId,
|
||
|
RAW_CONNECTION ** ppRawConnection
|
||
|
);
|
||
|
|
||
|
static
|
||
|
BOOL
|
||
|
WINAPI
|
||
|
RawFilterServerSupportFunction(
|
||
|
HTTP_FILTER_CONTEXT * pfc,
|
||
|
enum SF_REQ_TYPE SupportFunction,
|
||
|
void * pData,
|
||
|
ULONG_PTR ul,
|
||
|
ULONG_PTR ul2
|
||
|
);
|
||
|
|
||
|
static
|
||
|
BOOL
|
||
|
WINAPI
|
||
|
RawFilterGetServerVariable(
|
||
|
HTTP_FILTER_CONTEXT * pfc,
|
||
|
LPSTR lpszVariableName,
|
||
|
LPVOID lpvBuffer,
|
||
|
LPDWORD lpdwSize
|
||
|
);
|
||
|
|
||
|
static
|
||
|
BOOL
|
||
|
WINAPI
|
||
|
RawFilterWriteClient(
|
||
|
HTTP_FILTER_CONTEXT * pfc,
|
||
|
LPVOID Buffer,
|
||
|
LPDWORD lpdwBytes,
|
||
|
DWORD dwReserved
|
||
|
);
|
||
|
|
||
|
static
|
||
|
VOID *
|
||
|
WINAPI
|
||
|
RawFilterAllocateMemory(
|
||
|
HTTP_FILTER_CONTEXT * pfc,
|
||
|
DWORD cbSize,
|
||
|
DWORD dwReserved
|
||
|
);
|
||
|
|
||
|
static
|
||
|
BOOL
|
||
|
WINAPI
|
||
|
RawFilterAddResponseHeaders(
|
||
|
HTTP_FILTER_CONTEXT * pfc,
|
||
|
LPSTR lpszHeaders,
|
||
|
DWORD dwReserved
|
||
|
);
|
||
|
|
||
|
static
|
||
|
HRESULT
|
||
|
ProcessRawRead(
|
||
|
RAW_STREAM_INFO * pRawStreamInfo,
|
||
|
PVOID pvContext,
|
||
|
BOOL * pfReadMore,
|
||
|
BOOL * pfComplete,
|
||
|
DWORD * pcbNextReadSize
|
||
|
);
|
||
|
|
||
|
static
|
||
|
HRESULT
|
||
|
ProcessRawWrite(
|
||
|
RAW_STREAM_INFO * pRawStreamInfo,
|
||
|
PVOID pvContext,
|
||
|
BOOL * pfComplete
|
||
|
);
|
||
|
|
||
|
static
|
||
|
HRESULT
|
||
|
ProcessNewConnection(
|
||
|
CONNECTION_INFO * pConnectionInfo,
|
||
|
PVOID * ppvContext
|
||
|
);
|
||
|
|
||
|
static
|
||
|
VOID
|
||
|
ProcessConnectionClose(
|
||
|
VOID * pvContext
|
||
|
);
|
||
|
|
||
|
HRESULT
|
||
|
NotifyRawReadFilters(
|
||
|
RAW_STREAM_INFO * pRawStreamInfo,
|
||
|
BOOL * pfReadMore,
|
||
|
BOOL * pfComplete
|
||
|
);
|
||
|
|
||
|
HRESULT
|
||
|
NotifyRawWriteFilters(
|
||
|
RAW_STREAM_INFO * pRawStreamInfo,
|
||
|
BOOL * pfComplete,
|
||
|
DWORD dwStartFilter
|
||
|
);
|
||
|
|
||
|
HRESULT
|
||
|
SendResponseHeader(
|
||
|
CHAR * pszStatus,
|
||
|
CHAR * pszAdditionalHeaders,
|
||
|
HTTP_FILTER_CONTEXT * pfc
|
||
|
);
|
||
|
|
||
|
HRESULT
|
||
|
NotifyEndOfNetSessionFilters(
|
||
|
VOID
|
||
|
);
|
||
|
|
||
|
VOID
|
||
|
CopyAllocatedFilterMemory(
|
||
|
W3_FILTER_CONTEXT * pFilterContext
|
||
|
);
|
||
|
|
||
|
PVOID
|
||
|
AllocateFilterMemory(
|
||
|
DWORD cbSize
|
||
|
)
|
||
|
{
|
||
|
FILTER_POOL_ITEM * pPoolItem;
|
||
|
|
||
|
pPoolItem = FILTER_POOL_ITEM::CreateMemPoolItem( cbSize );
|
||
|
if ( pPoolItem != NULL )
|
||
|
{
|
||
|
InsertHeadList( &_PoolHead, &(pPoolItem->_ListEntry) );
|
||
|
return pPoolItem->_pvData;
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
CheckSignature(
|
||
|
VOID
|
||
|
) const
|
||
|
{
|
||
|
return _dwSignature == RAW_CONNECTION_SIGNATURE;
|
||
|
}
|
||
|
|
||
|
HTTP_RAW_CONNECTION_ID
|
||
|
QueryRawConnectionId(
|
||
|
VOID
|
||
|
) const
|
||
|
{
|
||
|
return _RawConnectionId;
|
||
|
}
|
||
|
|
||
|
W3_MAIN_CONTEXT *
|
||
|
QueryMainContext(
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
return _pMainContext;
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
SetMainContext(
|
||
|
W3_MAIN_CONTEXT * pNewContext
|
||
|
)
|
||
|
{
|
||
|
if ( _pMainContext != NULL )
|
||
|
{
|
||
|
_pMainContext->DereferenceMainContext();
|
||
|
}
|
||
|
|
||
|
if ( pNewContext != NULL )
|
||
|
{
|
||
|
pNewContext->ReferenceMainContext();
|
||
|
}
|
||
|
|
||
|
_pMainContext = pNewContext;
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
AddResponseHeaders(
|
||
|
LPSTR pszAddResponseHeaders
|
||
|
)
|
||
|
{
|
||
|
return _strAddResponseHeaders.Append( pszAddResponseHeaders );
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
AddDenialHeaders(
|
||
|
LPSTR pszAddDenialHeaders
|
||
|
)
|
||
|
{
|
||
|
return _strAddDenialHeaders.Append( pszAddDenialHeaders );
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
ReferenceRawConnection(
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
InterlockedIncrement( &_cRefs );
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
DereferenceRawConnection(
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
if ( !InterlockedDecrement( &_cRefs ) )
|
||
|
{
|
||
|
delete this;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DWORD
|
||
|
QueryNextReadSize(
|
||
|
VOID
|
||
|
) const
|
||
|
{
|
||
|
return _cbNextReadSize;
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
SetNextReadSize(
|
||
|
DWORD cbNextReadSize
|
||
|
)
|
||
|
{
|
||
|
_cbNextReadSize = cbNextReadSize;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// A bunch of functions which need to gate their execution on whether
|
||
|
// or not we have an associated W3_CONNECTION with the this raw connection
|
||
|
//
|
||
|
|
||
|
FILTER_LIST *
|
||
|
QueryFilterList(
|
||
|
VOID
|
||
|
);
|
||
|
|
||
|
BOOL
|
||
|
QueryNotificationChanged(
|
||
|
VOID
|
||
|
);
|
||
|
|
||
|
BOOL
|
||
|
IsDisableNotificationNeeded(
|
||
|
DWORD dwFilter,
|
||
|
DWORD dwNotification
|
||
|
);
|
||
|
|
||
|
PVOID
|
||
|
QueryClientContext(
|
||
|
DWORD dwFilter
|
||
|
);
|
||
|
|
||
|
VOID
|
||
|
SetClientContext(
|
||
|
DWORD dwFilter,
|
||
|
PVOID pvContext
|
||
|
);
|
||
|
|
||
|
VOID
|
||
|
CopyContextPointers(
|
||
|
W3_FILTER_CONTEXT * pFilterContext
|
||
|
);
|
||
|
|
||
|
HRESULT
|
||
|
CopyHeaders(
|
||
|
W3_FILTER_CONTEXT * pFilterContext
|
||
|
);
|
||
|
|
||
|
HRESULT
|
||
|
GetLimitedServerVariables(
|
||
|
LPSTR pszVariableName,
|
||
|
PVOID pvBuffer,
|
||
|
PDWORD pdwSize
|
||
|
);
|
||
|
|
||
|
static
|
||
|
HRESULT
|
||
|
AssociateW3Connection(
|
||
|
HTTP_RAW_CONNECTION_ID rawConnectionId,
|
||
|
W3_CONNECTION * pW3Connection
|
||
|
);
|
||
|
|
||
|
private:
|
||
|
DWORD _dwSignature;
|
||
|
LONG _cRefs;
|
||
|
|
||
|
//
|
||
|
// Filter opaque contexts
|
||
|
//
|
||
|
|
||
|
PVOID _rgContexts[ MAX_FILTERS ];
|
||
|
|
||
|
//
|
||
|
// List of pool items allocated by client. These pool items will be
|
||
|
// migrated to the W3_FILTER_CONNECTION_CONTEXT when possible
|
||
|
//
|
||
|
|
||
|
LIST_ENTRY _PoolHead;
|
||
|
|
||
|
//
|
||
|
// The filter descriptor passed to filters
|
||
|
//
|
||
|
|
||
|
HTTP_FILTER_CONTEXT _hfc;
|
||
|
|
||
|
//
|
||
|
// Current filter. This is used to handle WriteClient()s from
|
||
|
// read/write raw data filters
|
||
|
//
|
||
|
|
||
|
DWORD _dwCurrentFilter;
|
||
|
|
||
|
//
|
||
|
// A function/context to call back into stream filter
|
||
|
//
|
||
|
|
||
|
PFN_SEND_DATA_BACK _pfnSendDataBack;
|
||
|
PVOID _pvStreamContext;
|
||
|
|
||
|
//
|
||
|
// Local/remote port info
|
||
|
//
|
||
|
|
||
|
USHORT _LocalPort;
|
||
|
DWORD _LocalAddress;
|
||
|
USHORT _RemotePort;
|
||
|
DWORD _RemoteAddress;
|
||
|
|
||
|
//
|
||
|
// Raw connection id
|
||
|
//
|
||
|
|
||
|
HTTP_RAW_CONNECTION_ID _RawConnectionId;
|
||
|
|
||
|
//
|
||
|
// A response object which is needed if a raw read notification sends
|
||
|
// a response and then expects a send-response notification.
|
||
|
// (triple AAARRRRGGGGHH)
|
||
|
//
|
||
|
|
||
|
W3_RESPONSE _response;
|
||
|
|
||
|
//
|
||
|
// Main context which applies to this connection. There may be several
|
||
|
// during the life of this connection
|
||
|
//
|
||
|
|
||
|
W3_MAIN_CONTEXT * _pMainContext;
|
||
|
|
||
|
//
|
||
|
// While we haven't associated with a WP request, we need to keep track
|
||
|
// of our own additional response/denial headers
|
||
|
//
|
||
|
|
||
|
STRA _strAddDenialHeaders;
|
||
|
STRA _strAddResponseHeaders;
|
||
|
|
||
|
//
|
||
|
// Next read size (0 means use default size)
|
||
|
//
|
||
|
|
||
|
DWORD _cbNextReadSize;
|
||
|
|
||
|
static RAW_CONNECTION_HASH * sm_pRawConnectionHash;
|
||
|
|
||
|
};
|
||
|
|
||
|
//
|
||
|
// RAW_CONNECTION_HASH
|
||
|
//
|
||
|
|
||
|
class RAW_CONNECTION_HASH
|
||
|
: public CTypedHashTable<
|
||
|
RAW_CONNECTION_HASH,
|
||
|
RAW_CONNECTION,
|
||
|
ULONGLONG
|
||
|
>
|
||
|
{
|
||
|
public:
|
||
|
RAW_CONNECTION_HASH()
|
||
|
: CTypedHashTable< RAW_CONNECTION_HASH,
|
||
|
RAW_CONNECTION,
|
||
|
ULONGLONG > ( "RAW_CONNECTION_HASH" )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
static
|
||
|
ULONGLONG
|
||
|
ExtractKey(
|
||
|
const RAW_CONNECTION * pRawConnection
|
||
|
)
|
||
|
{
|
||
|
return pRawConnection->QueryRawConnectionId();
|
||
|
}
|
||
|
|
||
|
static
|
||
|
DWORD
|
||
|
CalcKeyHash(
|
||
|
ULONGLONG ullKey
|
||
|
)
|
||
|
{
|
||
|
return Hash( (DWORD) ullKey );
|
||
|
}
|
||
|
|
||
|
static
|
||
|
bool
|
||
|
EqualKeys(
|
||
|
ULONGLONG ullKey1,
|
||
|
ULONGLONG ullKey2
|
||
|
)
|
||
|
{
|
||
|
return ullKey1 == ullKey2;
|
||
|
}
|
||
|
|
||
|
static
|
||
|
void
|
||
|
AddRefRecord(
|
||
|
RAW_CONNECTION * pEntry,
|
||
|
int nIncr
|
||
|
)
|
||
|
{
|
||
|
if ( nIncr == +1 )
|
||
|
{
|
||
|
pEntry->ReferenceRawConnection();
|
||
|
}
|
||
|
else if ( nIncr == -1 )
|
||
|
{
|
||
|
pEntry->DereferenceRawConnection();
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
#endif
|