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
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_
|