396 lines
7.9 KiB
C++
396 lines
7.9 KiB
C++
#ifndef _ULCONTEXT_HXX_
|
|
#define _ULCONTEXT_HXX_
|
|
|
|
#define UL_CONTEXT_DESIRED_OUTSTANDING 20
|
|
#define UL_CONTEXT_INIT_BUFFER 1024
|
|
|
|
#define UL_CONTEXT_FLAG_ASYNC 0x00000001
|
|
#define UL_CONTEXT_FLAG_SYNC 0x00000002
|
|
|
|
#define UL_CONTEXT_SIGNATURE (DWORD)'XCLU'
|
|
#define UL_CONTEXT_SIGNATURE_FREE (DWORD)'xclu'
|
|
|
|
enum OVERLAPPED_CONTEXT_TYPE
|
|
{
|
|
OVERLAPPED_CONTEXT_RAW_READ = 0,
|
|
OVERLAPPED_CONTEXT_RAW_WRITE,
|
|
OVERLAPPED_CONTEXT_APP_READ,
|
|
OVERLAPPED_CONTEXT_APP_WRITE
|
|
};
|
|
|
|
class UL_CONTEXT;
|
|
class STREAM_CONTEXT;
|
|
|
|
class OVERLAPPED_CONTEXT
|
|
{
|
|
public:
|
|
|
|
friend
|
|
VOID
|
|
OverlappedCompletionRoutine(
|
|
DWORD dwErrorCode,
|
|
DWORD dwNumberOfBytesTransfered,
|
|
LPOVERLAPPED lpOverlapped
|
|
);
|
|
|
|
OVERLAPPED_CONTEXT(
|
|
OVERLAPPED_CONTEXT_TYPE type
|
|
)
|
|
{
|
|
_type = type;
|
|
ZeroMemory( &_Overlapped, sizeof( _Overlapped ) );
|
|
}
|
|
|
|
OVERLAPPED_CONTEXT_TYPE
|
|
QueryType(
|
|
VOID
|
|
) const
|
|
{
|
|
return _type;
|
|
}
|
|
|
|
VOID
|
|
SetContext(
|
|
UL_CONTEXT * pContext
|
|
)
|
|
{
|
|
_pContext = pContext;
|
|
}
|
|
|
|
UL_CONTEXT *
|
|
QueryContext(
|
|
VOID
|
|
) const
|
|
{
|
|
return _pContext;
|
|
}
|
|
|
|
OVERLAPPED *
|
|
QueryOverlapped(
|
|
VOID
|
|
)
|
|
{
|
|
return &_Overlapped;
|
|
}
|
|
|
|
private:
|
|
OVERLAPPED _Overlapped;
|
|
UL_CONTEXT * _pContext;
|
|
OVERLAPPED_CONTEXT_TYPE _type;
|
|
};
|
|
|
|
class UL_CONTEXT
|
|
{
|
|
public:
|
|
UL_CONTEXT();
|
|
|
|
virtual ~UL_CONTEXT();
|
|
|
|
BOOL
|
|
CheckSignature(
|
|
VOID
|
|
) const
|
|
{
|
|
return _dwSignature == UL_CONTEXT_SIGNATURE;
|
|
}
|
|
|
|
OVERLAPPED *
|
|
QueryRawWriteOverlapped(
|
|
VOID
|
|
)
|
|
{
|
|
return _RawWriteOverlapped.QueryOverlapped();
|
|
}
|
|
|
|
OVERLAPPED *
|
|
QueryRawReadOverlapped(
|
|
VOID
|
|
)
|
|
{
|
|
return _RawReadOverlapped.QueryOverlapped();
|
|
}
|
|
|
|
OVERLAPPED *
|
|
QueryAppWriteOverlapped(
|
|
VOID
|
|
)
|
|
{
|
|
return _AppWriteOverlapped.QueryOverlapped();
|
|
}
|
|
|
|
OVERLAPPED *
|
|
QueryAppReadOverlapped(
|
|
VOID
|
|
)
|
|
{
|
|
return _AppReadOverlapped.QueryOverlapped();
|
|
}
|
|
|
|
HTTP_RAW_CONNECTION_INFO *
|
|
QueryConnectionInfo(
|
|
VOID
|
|
) const
|
|
{
|
|
return _pConnectionInfo;
|
|
}
|
|
|
|
VOID
|
|
ReferenceUlContext(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
DereferenceUlContext(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
SetIsSecure(
|
|
BOOL fIsSecure
|
|
)
|
|
{
|
|
_connectionContext.fIsSecure = fIsSecure;
|
|
}
|
|
|
|
HRESULT
|
|
OnRawReadCompletion(
|
|
DWORD cbCompletion,
|
|
DWORD dwCompletionStatus
|
|
);
|
|
|
|
HRESULT
|
|
OnRawWriteCompletion(
|
|
DWORD cbCompletion,
|
|
DWORD dwCompletionStatus
|
|
);
|
|
|
|
HRESULT
|
|
OnAppWriteCompletion(
|
|
DWORD cbCompletion,
|
|
DWORD dwCompletionStatus
|
|
);
|
|
|
|
HRESULT
|
|
OnAppReadCompletion(
|
|
DWORD cbCompletion,
|
|
DWORD dwCompletionStatus
|
|
);
|
|
|
|
HRESULT
|
|
DoRawRead(
|
|
DWORD dwFlags,
|
|
PVOID pvBuffer,
|
|
DWORD cbBuffer,
|
|
DWORD * pcbRead
|
|
);
|
|
|
|
HRESULT
|
|
DoRawWrite(
|
|
DWORD dwFlags,
|
|
PVOID pvBuffer,
|
|
DWORD cbBuffer,
|
|
DWORD * pcbWritten
|
|
);
|
|
|
|
HRESULT
|
|
DoAppRead(
|
|
DWORD dwFlags,
|
|
HTTP_FILTER_BUFFER * pFilterBuffer,
|
|
DWORD * pcbRead
|
|
);
|
|
|
|
HRESULT
|
|
DoAppWrite(
|
|
DWORD dwFlags,
|
|
HTTP_FILTER_BUFFER * pFilterBuffer,
|
|
DWORD * pcbWritten
|
|
);
|
|
|
|
DWORD
|
|
QueryNextRawReadSize(
|
|
VOID
|
|
) const
|
|
{
|
|
return _cbNextRawReadSize;
|
|
}
|
|
|
|
VOID
|
|
SetNextRawReadSize(
|
|
DWORD dwRawReadSize
|
|
)
|
|
{
|
|
DBG_ASSERT( dwRawReadSize != 0 );
|
|
_cbNextRawReadSize = dwRawReadSize;
|
|
}
|
|
|
|
HTTP_FILTER_BUFFER_TYPE
|
|
QueryFilterBufferType(
|
|
VOID
|
|
) const
|
|
{
|
|
DBG_ASSERT( _ulFilterBufferType != (HTTP_FILTER_BUFFER_TYPE)-1 );
|
|
return _ulFilterBufferType;
|
|
}
|
|
|
|
HRESULT
|
|
SendDataBack(
|
|
RAW_STREAM_INFO * pRawStreamInfo
|
|
);
|
|
|
|
VOID
|
|
StartClose(
|
|
VOID
|
|
);
|
|
|
|
HRESULT
|
|
Create(
|
|
VOID
|
|
);
|
|
|
|
HRESULT
|
|
DoAccept(
|
|
VOID
|
|
);
|
|
|
|
static
|
|
HRESULT
|
|
Initialize(
|
|
LPWSTR pChannelName
|
|
);
|
|
|
|
static
|
|
VOID
|
|
Terminate(
|
|
VOID
|
|
);
|
|
|
|
static
|
|
VOID
|
|
WaitForContextDrain(
|
|
VOID
|
|
);
|
|
|
|
static
|
|
HRESULT
|
|
ManageOutstandingContexts(
|
|
VOID
|
|
);
|
|
|
|
static
|
|
VOID
|
|
StopListening(
|
|
VOID
|
|
);
|
|
|
|
private:
|
|
DWORD _dwSignature;
|
|
|
|
//
|
|
// Reference count (duh)
|
|
//
|
|
|
|
LONG _cRefs;
|
|
|
|
//
|
|
// Keep a list of UL_CONTEXTs
|
|
//
|
|
|
|
LIST_ENTRY _ListEntry;
|
|
|
|
//
|
|
// Since we will pending two operations (read from net, write from process)
|
|
// we need two overlapped structures and a way to determine which one
|
|
// completed
|
|
//
|
|
|
|
OVERLAPPED_CONTEXT _RawReadOverlapped;
|
|
OVERLAPPED_CONTEXT _RawWriteOverlapped;
|
|
OVERLAPPED_CONTEXT _AppReadOverlapped;
|
|
OVERLAPPED_CONTEXT _AppWriteOverlapped;
|
|
|
|
//
|
|
// SSL stream context
|
|
//
|
|
|
|
STREAM_CONTEXT * _pSSLContext;
|
|
|
|
#ifdef ISAPI
|
|
//
|
|
// ISAPI raw data filter context
|
|
//
|
|
|
|
STREAM_CONTEXT * _pISAPIContext;
|
|
#endif
|
|
|
|
//
|
|
// The initial ULFilterAccept structure
|
|
//
|
|
|
|
HTTP_RAW_CONNECTION_INFO* _pConnectionInfo;
|
|
BUFFER _buffConnectionInfo;
|
|
BYTE _abConnectionInfo[ UL_CONTEXT_INIT_BUFFER ];
|
|
CONNECTION_INFO _connectionContext;
|
|
|
|
//
|
|
// Pointer and size of read stream data
|
|
//
|
|
|
|
BUFFER _buffReadData;
|
|
DWORD _cbReadData;
|
|
|
|
//
|
|
// Filter buffer for read app data
|
|
//
|
|
|
|
BUFFER _buffAppReadData;
|
|
HTTP_FILTER_BUFFER _ulFilterBuffer;
|
|
|
|
//
|
|
// Close flag. One thread takes the responsibility of doing the close
|
|
// dereference of this object (leading to its destruction once down
|
|
// stream user (STREAM_CONTEXT) has cleaned up
|
|
//
|
|
|
|
BOOL _fCloseConnection;
|
|
|
|
//
|
|
// If this a new connection?
|
|
//
|
|
|
|
BOOL _fNewConnection;
|
|
|
|
//
|
|
// Next read size
|
|
//
|
|
|
|
DWORD _cbNextRawReadSize;
|
|
|
|
//
|
|
// Filter buffer type read from application
|
|
//
|
|
|
|
HTTP_FILTER_BUFFER_TYPE _ulFilterBufferType;
|
|
|
|
//
|
|
// UL_CONTEXT globals
|
|
//
|
|
|
|
static LIST_ENTRY sm_ListHead;
|
|
static CRITICAL_SECTION sm_csUlContexts;
|
|
static DWORD sm_cUlContexts;
|
|
static HANDLE sm_hFilterHandle;
|
|
static THREAD_POOL * sm_pThreadPool;
|
|
static LONG sm_cOutstandingContexts;
|
|
static LONG sm_cDesiredOutstanding;
|
|
static PTRACE_LOG sm_pTraceLog;
|
|
};
|
|
|
|
VOID
|
|
OverlappedCompletionRoutine(
|
|
DWORD dwErrorCode,
|
|
DWORD dwNumberOfBytesTransfered,
|
|
LPOVERLAPPED lpOverlapped
|
|
);
|
|
|
|
#endif
|