📄 isapi.cpp
字号:
*(_STACK_INT*)pStack = *((WORD*) pRawParam);
pStack += sizeof(_STACK_INT); // 'short' is passed as 'int'
break;
case IT_I4:
*(_STACK_LONG*)pStack = *((DWORD*) pRawParam);
pStack += sizeof(_STACK_LONG);
break;
case IT_R4:
*(_STACK_FLOAT*)pStack = *((_STACK_FLOAT*) pRawParam);
pStack += sizeof(_STACK_FLOAT);
#ifdef _SHADOW_DOUBLES
if (pDoubleShadow < pDoubleShadowMax)
*pDoubleShadow++ = *((_STACK_DOUBLE*) pRawParam);
#endif
break;
case IT_R8:
#ifdef _ALIGN_DOUBLES
// align doubles on 8 byte for some platforms
pStack = (BYTE*)(((DWORD)pStack + _ALIGN_DOUBLES-1) &
~(_ALIGN_DOUBLES-1));
#endif
*(_STACK_DOUBLE*)pStack = *((_STACK_DOUBLE*) pRawParam);
pStack += sizeof(_STACK_DOUBLE);
#ifdef _SHADOW_DOUBLES
if (pDoubleShadow < pDoubleShadowMax)
*pDoubleShadow++ = *((_STACK_DOUBLE*) pRawParam);
#endif
break;
case IT_PSTR:
*(_STACK_PTR*)pStack = *((_STACK_PTR*) pRawParam);
pStack += sizeof(_STACK_PTR);
break;
default:
ISAPIASSERT(FALSE);
}
#ifdef _ALIGN_STACK
// align stack as appropriate for next parameter
pStack = (BYTE*)(((DWORD)pStack + (_ALIGN_STACK-1)) &
~(_ALIGN_STACK-1));
ISAPIASSERT(((DWORD)pStack & (_ALIGN_STACK-1)) == 0);
#endif
return pStack;
}
#ifndef _SHADOW_DOUBLES
BYTE* CHttpServer::StoreStackParameter(BYTE* pStack, BYTE nType,
LPTSTR pszCurParam)
#else
BYTE* CHttpServer::StoreStackParameter(BYTE* pStack, BYTE nType,
LPTSTR pszCurParam, UINT nSizeArgs, BOOL bDoShadow)
#endif
{
ISAPIASSERT(pStack != NULL);
ISAPIASSERT(pszCurParam != NULL);
#ifdef _SHADOW_DOUBLES
double* pDoubleShadow = (double*)(pStack + nSizeArgs);
double* pDoubleShadowMax = pDoubleShadow + _SHADOW_DOUBLES;
#endif
// push parameter value on the stack
switch (nType)
{
// by value parameters
case IT_I2:
*(_STACK_INT*)pStack = (WORD) _ttoi(pszCurParam);
pStack += sizeof(_STACK_INT); // 'short' is passed as 'int'
break;
case IT_I4:
*(_STACK_LONG*)pStack = (DWORD) _ttol(pszCurParam);
pStack += sizeof(_STACK_LONG);
break;
case IT_R4:
*(_STACK_FLOAT*)pStack = (_STACK_FLOAT) atof(pszCurParam);
pStack += sizeof(_STACK_FLOAT);
#ifdef _SHADOW_DOUBLES
if (bDoShadow && pDoubleShadow < pDoubleShadowMax)
*pDoubleShadow++ = (double) atof(pszCurParam);
#endif
break;
case IT_R8:
#ifdef _ALIGN_DOUBLES
// align doubles on 8 byte for some platforms
pStack = (BYTE*)(((DWORD)pStack + _ALIGN_DOUBLES-1) &
~(_ALIGN_DOUBLES-1));
#endif
*(_STACK_DOUBLE*)pStack = (_STACK_DOUBLE) atof(pszCurParam);
pStack += sizeof(_STACK_DOUBLE);
#ifdef _SHADOW_DOUBLES
if (bDoShadow && pDoubleShadow < pDoubleShadowMax)
*pDoubleShadow++ = atof(pszCurParam);
#endif
break;
case IT_PSTR:
*(_STACK_PTR*)pStack = (_STACK_PTR) PreprocessString(pszCurParam);
pStack += sizeof(_STACK_PTR);
break;
default:
ISAPIASSERT(FALSE);
}
#ifdef _ALIGN_STACK
// align stack as appropriate for next parameter
pStack = (BYTE*)(((DWORD)pStack + (_ALIGN_STACK-1)) &
~(_ALIGN_STACK-1));
ISAPIASSERT(((DWORD)pStack & (_ALIGN_STACK-1)) == 0);
#endif
return pStack;
}
LPVOID CHttpServer::PreprocessString(LPTSTR psz)
{
LPTSTR pszSource = psz;
LPTSTR pszDest = psz;
static const TCHAR szHex[] = _T("0123456789ABCDEF");
// unescape special characters
while (*pszSource != '\0')
{
if (*pszSource == '+')
*pszDest++ = ' ';
else if (*pszSource == '%')
{
TCHAR nValue = '?';
LPCTSTR pszLow;
LPCTSTR pszHigh;
pszSource++;
*pszSource = (TCHAR) _totupper(*pszSource);
pszHigh = _tcschr(szHex, *pszSource);
if (pszHigh != NULL)
{
pszSource++;
*pszSource = (TCHAR) _totupper(*pszSource);
pszLow = _tcschr(szHex, *pszSource);
if (pszLow != NULL)
{
nValue = (TCHAR) (((pszHigh - szHex) << 4) +
(pszLow - szHex));
}
}
*pszDest++ = nValue;
}
else
*pszDest++ = *pszSource;
pszSource++;
}
*pszDest = '\0';
return (LPVOID) psz;
}
///////////////////////////////////////////////////////////////////////
// in-memory HTML Stream
CHtmlStream::CHtmlStream(UINT nGrowBytes /* = 4096 */)
{
ISAPIASSERT(nGrowBytes <= UINT_MAX && nGrowBytes >= 0);
m_nGrowBytes = nGrowBytes;
m_nPosition = 0;
m_nBufferSize = 0;
m_lpBuffer = NULL;
m_bAutoDelete = TRUE;
m_nStreamSize = 0;
}
CHtmlStream::CHtmlStream(BYTE* lpBuffer, UINT nBufferSize,
UINT nGrowBytes /* = 0 */)
{
ISAPIASSERT(nGrowBytes <= UINT_MAX && nGrowBytes >= 0);
m_nGrowBytes = nGrowBytes;
m_nPosition = 0;
m_nBufferSize = nBufferSize;
// if the caller provides a grow-by size, use it;
// otherwise, incrememt by the initial buffer size
m_nStreamSize = nGrowBytes == 0 ? nBufferSize : 0;
m_lpBuffer = lpBuffer;
m_bAutoDelete = FALSE;
}
void CHtmlStream::Attach(BYTE* lpBuffer, UINT nBufferSize, UINT nGrowBytes)
{
ISAPIASSERT(m_lpBuffer == NULL);
m_nGrowBytes = nGrowBytes;
m_nPosition = 0;
m_nBufferSize = nBufferSize;
// if the caller provides a grow-by size, use it;
// otherwise, incrememt by the initial buffer size
m_nStreamSize = nGrowBytes == 0 ? nBufferSize : 0;
m_lpBuffer = lpBuffer;
m_bAutoDelete = FALSE;
}
BYTE* CHtmlStream::Detach()
{
BYTE* lpBuffer = NULL;
if (m_lpBuffer != NULL)
{
TCHAR chZero = 0;
Write(&chZero, sizeof(TCHAR));
lpBuffer = m_lpBuffer;
m_lpBuffer = NULL;
}
m_nBufferSize = 0;
m_nStreamSize = 0;
m_nPosition = 0;
return lpBuffer;
}
CHtmlStream::~CHtmlStream()
{
// Close should have already been called, but we check anyway
if (m_lpBuffer)
Close();
ISAPIASSERT(NULL == m_lpBuffer);
m_nGrowBytes = 0;
m_nPosition = 0;
m_nStreamSize = 0;
m_nBufferSize = 0;
}
BYTE* CHtmlStream::Alloc(DWORD nBytes)
{
return (BYTE*)malloc((UINT)nBytes);
}
BYTE* CHtmlStream::Realloc(BYTE* lpMem, DWORD nBytes)
{
return (BYTE*)realloc(lpMem, (UINT)nBytes);
}
#pragma intrinsic(memcpy)
BYTE* CHtmlStream::Memcpy(BYTE* lpMemTarget, const BYTE* lpMemSource,
UINT nBytes)
{
ISAPIASSERT(lpMemTarget != NULL);
ISAPIASSERT(lpMemSource != NULL);
return (BYTE*)memcpy(lpMemTarget, lpMemSource, nBytes);
}
#pragma function(memcpy)
void CHtmlStream::Free(BYTE* lpMem)
{
ISAPIASSERT(lpMem != NULL);
free(lpMem);
}
void CHtmlStream::GrowStream(DWORD dwNewLen)
{
if (dwNewLen > m_nBufferSize)
{
// grow the buffer
DWORD dwNewBufferSize = (DWORD)m_nBufferSize;
// watch out for buffers which cannot be grown!
ISAPIASSERT(m_nGrowBytes > 0);
if (m_nGrowBytes == 0)
throw;
// determine new buffer size
while (dwNewBufferSize < dwNewLen)
dwNewBufferSize += m_nGrowBytes;
// allocate new buffer
BYTE* lpNew;
if (m_lpBuffer == NULL)
lpNew = Alloc(dwNewBufferSize);
else
lpNew = Realloc(m_lpBuffer, dwNewBufferSize);
if (lpNew == NULL)
throw;
m_lpBuffer = lpNew;
m_nBufferSize = dwNewBufferSize;
}
}
CHtmlStream& CHtmlStream::operator<<(LPCTSTR psz)
{
Write(psz, lstrlen(psz));
return *this;
}
CHtmlStream& CHtmlStream::operator<<(short int w)
{
TCHAR sz[16];
int nLen = wsprintf(sz, szDecimalFormat, w);
Write(sz, nLen);
return *this;
}
CHtmlStream& CHtmlStream::operator<<(long int dw)
{
TCHAR sz[16];
int nLen = wsprintf(sz, szDecimalFormat, dw);
Write(sz, nLen);
return *this;
}
CHtmlStream& CHtmlStream::operator<<(float f)
{
TCHAR sz[512];
int nLen = _stprintf(sz, szFloatFormat, f);
Write(sz, nLen);
return *this;
}
CHtmlStream& CHtmlStream::operator<<(double d)
{
TCHAR sz[512];
int nLen = _stprintf(sz, szFloatFormat, d);
Write(sz, nLen);
return *this;
}
CHtmlStream& CHtmlStream::operator<<(const CHtmlStream& stream)
{
DWORD dwSourceLen = stream.GetStreamSize();
Write(stream.m_lpBuffer, dwSourceLen);
return *this;
}
void CHtmlStream::Close()
{
m_nGrowBytes = 0;
m_nPosition = 0;
m_nBufferSize = 0;
m_nStreamSize = 0;
if (m_lpBuffer && m_bAutoDelete)
Free(m_lpBuffer);
m_lpBuffer = NULL;
}
void CHtmlStream::Abort()
{
Close();
}
void CHtmlStream::Write(const void* lpBuf, UINT nCount)
{
if (nCount == 0)
return;
ISAPIASSERT(lpBuf != NULL);
if (m_nPosition + nCount > m_nBufferSize)
GrowStream(m_nPosition + nCount);
ISAPIASSERT(m_nPosition + nCount <= m_nBufferSize);
Memcpy((BYTE*)m_lpBuffer + m_nPosition, (BYTE*)lpBuf, nCount);
m_nPosition += nCount;
if (m_nPosition > m_nStreamSize)
m_nStreamSize = m_nPosition;
}
void CHtmlStream::Reset()
{
m_nPosition = 0;
m_nStreamSize = 0;
}
void CHtmlStream::InitStream()
{
// subclass can override for interesting applications
}
///////////////////////////////////////////////////////////////////////
// HTTP Filter entry points
extern "C" DWORD WINAPI HttpFilterProc(PHTTP_FILTER_CONTEXT pfc,
DWORD dwNotificationType, LPVOID pvNotification)
{
#ifdef _AFXDLL
AFX_MANAGE_STATE(AfxGetStaticModuleState());
#endif
DWORD dwRet;
ISAPIASSERT(pFilter != NULL);
if (pFilter == NULL)
dwRet = SF_STATUS_REQ_NEXT_NOTIFICATION;
else
dwRet = pFilter->HttpFilterProc(pfc,
dwNotificationType, pvNotification);
return dwRet;
}
extern "C" BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer)
{
#ifdef _AFXDLL
AFX_MANAGE_STATE(AfxGetStaticModuleState());
#endif
BOOL bRet;
ISAPIASSERT(pFilter != NULL);
if (pFilter == NULL)
bRet = FALSE;
else
bRet = pFilter->GetFilterVersion(pVer);
return bRet;
}
///////////////////////////////////////////////////////////////////////
// CHttpFilter implementation
CHttpFilter::CHttpFilter()
{
ISAPIASSERT(pFilter == NULL);
pFilter = this;
}
CHttpFilter::~CHttpFilter()
{
pFilter = NULL;
}
BOOL CHttpFilter::GetFilterVersion(PHTTP_FILTER_VERSION pVer)
{
pVer->dwFlags = SF_NOTIFY_ORDER_DEFAULT;
pVer->dwFilterVersion = HTTP_FILTER_REVISION;
pVer->lpszFilterDesc[0] = '\0';
return TRUE;
}
DWORD CHttpFilter::HttpFilterProc(PHTTP_FILTER_CONTEXT pfc,
DWORD dwNotificationType, LPVOID pvNotification)
{
DWORD dwRet = SF_STATUS_REQ_NEXT_NOTIFICATION;
CHttpFilterContext callCtxt(pfc);
switch (dwNotificationType)
{
case SF_NOTIFY_READ_RAW_DATA:
dwRet = OnReadRawData(&callCtxt, (PHTTP_FILTER_RAW_DATA) pvNotification);
break;
case SF_NOTIFY_PREPROC_HEADERS:
dwRet = OnPreprocHeaders(&callCtxt,
(PHTTP_FILTER_PREPROC_HEADERS) pvNotification);
break;
case SF_NOTIFY_AUTHENTICATION:
dwRet = OnAuthentication(&callCtxt,
(PHTTP_FILTER_AUTHENT) pvNotification);
break;
case SF_NOTIFY_URL_MAP:
dwRet = OnUrlMap(&callCtxt, (PHTTP_FILTER_URL_MAP) pvNotification);
break;
case SF_NOTIFY_SEND_RAW_DATA:
dwRet = OnSendRawData(&callCtxt, (PHTTP_FILTER_RAW_DATA) pvNotification);
break;
case SF_NOTIFY_LOG:
dwRet = OnLog(&callCtxt, (PHTTP_FILTER_LOG) pvNotification);
break;
case SF_NOTIFY_END_OF_NET_SESSION:
dwRet = OnEndOfNetSession(&callCtxt);
break;
case SF_NOTIFY_END_OF_REQUEST:
dwRet = OnEndOfRequest(&callCtxt);
break;
default:
ISAPITRACE1("Warning: unrecognized HTTP filter notification code %d\n", dwNotificationType);
break;
}
return dwRet;
}
// The user will override these. Here, the functions have no
// formal parameters to avoid warnings.
DWORD CHttpFilter::OnReadRawData(CHttpFilterContext*, PHTTP_FILTER_RAW_DATA)
{
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
DWORD CHttpFilter::OnPreprocHeaders(CHttpFilterContext*, PHTTP_FILTER_PREPROC_HEADERS)
{
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
DWORD CHttpFilter::OnAuthentication(CHttpFilterContext*, PHTTP_FILTER_AUTHENT)
{
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
DWORD CHttpFilter::OnUrlMap(CHttpFilterContext*, PHTTP_FILTER_URL_MAP)
{
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
DWORD CHttpFilter::OnSendRawData(CHttpFilterContext*, PHTTP_FILTER_RAW_DATA)
{
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
DWORD CHttpFilter::OnLog(CHttpFilterContext*, PHTTP_FILTER_LOG)
{
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
DWORD CHttpFilter::OnEndOfNetSession(CHttpFilterContext*)
{
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
DWORD CHttpFilter::OnEndOfRequest(CHttpFilterContext*)
{
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
///////////////////////////////////////////////////////////////////////
// tracing helper function for linking without MFC
#ifndef _AFX
#ifdef _DEBUG
void AFXISAPI_CDECL AfxISAPITrace(LPCTSTR lpszFormat, ...)
{
va_list args;
va_start(args, lpszFormat);
// if the trace has been set to go to a window and the user
// presses RETRY, we will break to the debugger here
if (_CrtDbgReport(_CRT_WARN, NULL, 0, NULL, lpszFormat, args) == 1)
_CrtDbgBreak();
va_end(args);
}
#endif
#endif
///////////////////////////////////////////////////////////////////////
// handle inline functions
#ifndef _AFX_ENABLE_INLINES
static const char _szAfxWinInl[] = "isapi.inl";
#undef THIS_FILE
#define THIS_FILE _szAfxWinInl
#define _AFXISAPI_INLINE
#include "afxisapi.inl"
#endif //!_AFX_ENABLE_INLINES
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -