|
|
/*++
Copyright (c) 2001 Microsoft Corporation
Module Name : isapi_context.hxx
Abstract: defines ISAPI_CONTEXT object
Author: Wade A. Hilmo (wadeh)
Revision History:
--*/
#ifndef _ISAPI_CONTEXT_HXX_
#define _ISAPI_CONTEXT_HXX_
#include "precomp.hxx"
#include "dll_manager.h"
//
// This is private hack for us done by COM team
//
const IID IID_IComDispatchInfo = {0x000001d9,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
MIDL_INTERFACE("000001d9-0000-0000-C000-000000000046") IComDispatchInfo : public IUnknown { public: virtual HRESULT STDMETHODCALLTYPE EnableComInits( /* [out] */ void __RPC_FAR *__RPC_FAR *ppvCookie) = 0; virtual HRESULT STDMETHODCALLTYPE DisableComInits( /* [in] */ void __RPC_FAR *pvCookie) = 0; };
//
// Ok, so the ISAPI_CONTEXT_SIGNATURE is weird. This is because, for
// compatibility purposes, the first member of the ISAPI_CONTEXT must
// be the ECB. Since the ECB is a large structure, and its size is
// fixed (and it's a public header that does this, so it's
// not likely to change), we'll be sneaky and use that size as the
// signature.
//
// This lets us maintain compatibility, and immediately recognize a
// freed object in the debugger without dumping a bunch of memory.
//
#define ISAPI_CONTEXT_SIGNATURE sizeof( EXTENSION_CONTROL_BLOCK )
#define ISAPI_CONTEXT_SIGNATURE_FREE 0xbadbad00 | sizeof( EXTENSION_CONTROL_BLOCK )
//
// The SERVER_VARIABLE_INDEX is an OOP optimization. The listed
// server variables can all be handled from data held in the
// ISAPI_CORE_DATA. In the OOP case, we can save an RPC call
// by doing this. It's not worth it in the inproc case, since
// these server variables are pretty cheap there.
//
enum SERVER_VARIABLE_INDEX { ServerVariableExternal = 0, ServerVariableApplMdPath, ServerVariableUnicodeApplMdPath, ServerVariableContentLength, ServerVariableContentType, ServerVariableInstanceId, ServerVariablePathInfo, ServerVariablePathTranslated, ServerVariableUnicodePathTranslated, ServerVariableQueryString, ServerVariableRequestMethod, ServerVariableServerPortSecure, ServerVariableServerProtocol, ServerVariableHttpMethod, ServerVariableHttpVersion, ServerVariableHttpCookie, ServerVariableHttpConnection };
SERVER_VARIABLE_INDEX LookupServerVariableIndex( LPSTR szServerVariable );
enum ASYNC_PENDING { NoAsyncIoPending = 0, AsyncWritePending, AsyncReadPending, AsyncExecPending, AsyncVectorPending };
class ISAPI_CONTEXT { public:
//
// Object allocation and lifetime control
//
ISAPI_CONTEXT( IIsapiCore * pIsapiCore, ISAPI_CORE_DATA * pCoreData, ISAPI_DLL * pIsapiDll );
VOID ReferenceIsapiContext( VOID );
VOID DereferenceIsapiContext( VOID );
VOID * operator new( size_t uiSize, VOID * pPlacement ) { IIsapiCore * pIsapiCore; DWORD64 ul64Block; HRESULT hr; ULARGE_INTEGER li;
if ( g_pDllManager->IsInproc() ) { pIsapiCore = (IIsapiCore*) pPlacement; DBG_ASSERT( pIsapiCore != NULL ); hr = pIsapiCore->AllocateMemory( (DWORD) uiSize, &ul64Block ); if ( FAILED( hr ) ) { return NULL; }
li.QuadPart = ul64Block;
#ifdef _WIN64
return (VOID*) li.QuadPart; #else
return (VOID*) li.LowPart; #endif
} else { if ( uiSize != sizeof( ISAPI_CONTEXT ) ) { DBG_ASSERT( FALSE ); return NULL; }
DBG_ASSERT( sm_pachIsapiContexts != NULL ); return sm_pachIsapiContexts->Alloc(); } } VOID operator delete( VOID * pIsapiContext ) { if ( g_pDllManager->IsInproc() ) { //
// Do nothing since the memory is in the local request heap
//
} else { DBG_ASSERT( sm_pachIsapiContexts != NULL ); sm_pachIsapiContexts->Free( pIsapiContext ); } }
BOOL CheckSignature() { return ( _ECB.cbSize == ISAPI_CONTEXT_SIGNATURE ); } static HRESULT Initialize( VOID ); static VOID Terminate( VOID );
//
// Accessors
//
EXTENSION_CONTROL_BLOCK * QueryECB( VOID ) { DBG_ASSERT( CheckSignature() );
return &_ECB; }
IIsapiCore * QueryIsapiCoreInterface( VOID ) { DBG_ASSERT( CheckSignature() ); DBG_ASSERT( _pIsapiCore != NULL );
return _pIsapiCore; }
BOOL QueryIsOop( VOID ) { DBG_ASSERT( CheckSignature() );
return _pCoreData->fIsOop; }
BOOL QueryClientKeepConn( VOID ) { return _fClientWantsKeepConn; }
BOOL QueryKeepConn( VOID ) { return _fDoKeepConn; }
VOID SetKeepConn( BOOL fKeepConn ) { _fDoKeepConn = fKeepConn; }
BOOL QueryHonorAndKeepConn( ) { return _fHonorAndKeepConn; }
VOID SetHonorAndKeepConn( BOOL fHonorAndKeepConn ) { _fHonorAndKeepConn = fHonorAndKeepConn; }
BOOL QueryHeadersSent( VOID ) { return _fHeadersSent; }
VOID SetHeadersSent( BOOL fHeadersSent ) { _fHeadersSent = fHeadersSent; }
ASYNC_PENDING QueryIoState( VOID ) { return _AsyncPending; }
LPVOID QueryAsyncIoBuffer( VOID ) { return _pvAsyncIoBuffer; }
VOID SetAsyncIoBuffer( LPVOID pBuffer ) { _pvAsyncIoBuffer = pBuffer; }
PFN_HSE_IO_COMPLETION QueryPfnIoCompletion( VOID ) { return _pfnHseIoCompletion; }
VOID SetPfnIoCompletion( PFN_HSE_IO_COMPLETION pfnHseIoCompletion ) { DBG_ASSERT( pfnHseIoCompletion ); _pfnHseIoCompletion = pfnHseIoCompletion; }
LPVOID QueryExtensionContext( VOID ) { return _pvHseIoContext; }
VOID SetExtensionContext( LPVOID pExtensionContext ) { _pvHseIoContext = pExtensionContext; }
DWORD QueryLastAsyncIo( VOID ) { return _cbLastAsyncIo; }
VOID SetLastAsyncIo( DWORD cbIo ) { _cbLastAsyncIo = cbIo; }
HANDLE QueryToken( VOID ) { DBG_ASSERT( _pCoreData->hToken != NULL ); return _pCoreData->hToken; }
LPWSTR QueryClsid( VOID ) { return _pCoreData->szWamClsid; }
HTTP_REQUEST_ID QueryRequestId( VOID ) { return _RequestId; }
LPWSTR QueryGatewayImage( VOID ) { return _pCoreData->szGatewayImage; }
//
// Helper functions
//
BOOL TryInitAsyncIo( ASYNC_PENDING IoType );
ASYNC_PENDING UninitAsyncIo( VOID );
VOID IsapiDoRevertHack( HANDLE * phToken, BOOL fForce = FALSE );
VOID IsapiUndoRevertHack( HANDLE * phToken );
BOOL GetOopServerVariableByIndex ( SERVER_VARIABLE_INDEX Index, LPVOID lpvBuffer, LPDWORD lpdwSize );
HRESULT SetComStateForOop( VOID );
VOID RestoreComStateForOop( VOID );
private:
~ISAPI_CONTEXT();
//
// The EXTENSION_CONTROL_BLOCK
//
// Don't be a biscuit head and put anything into the ISAPI_CONTEXT
// before the ECB. This is because some extensions pass a pointer to the
// ECB into ISAPI calls instead of the ConnID. Due to the layout of
// structures in previous versions of IIS, this worked, so we need to
// continue to support it.
//
EXTENSION_CONTROL_BLOCK _ECB;
//
// Core server information
//
IIsapiCore * _pIsapiCore; ISAPI_CORE_DATA * _pCoreData; ISAPI_DLL * _pIsapiDll;
//
// Async I/O management
//
ASYNC_PENDING _AsyncPending; DWORD _cbLastAsyncIo; PFN_HSE_IO_COMPLETION _pfnHseIoCompletion; LPVOID _pvHseIoContext; LPVOID _pvAsyncIoBuffer;
//
// Client connection management
//
BOOL _fClientWantsKeepConn; BOOL _fDoKeepConn; BOOL _fHonorAndKeepConn; BOOL _fHeadersSent;
//
// COM context info (for enabling CoInit/Uninit in OOP case)
//
IComDispatchInfo * _pComContext; void * _pComInitsCookie;
//
// Request id for tracing purposes
//
HTTP_REQUEST_ID _RequestId;
//
// Misc stuff for acache, trace log, lifetime control, object
// validation, etc.
//
LONG _cRefs;
static PTRACE_LOG sm_pTraceLog; static ALLOC_CACHE_HANDLER * sm_pachIsapiContexts; };
#endif // _ISAPI_CONTEXT_HXX_
|