Leaked source code of windows server 2003
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.
 
 
 
 
 
 

509 lines
10 KiB

/*++
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_