⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 isapi.cpp

📁 vc6.0完整版
💻 CPP
📖 第 1 页 / 共 4 页
字号:

		if (nRet == 0)
		{
			DWORD (AFXISAPI *pfnInet)(AFX_PISAPICMD, void*, UINT) =
				&_AfxParseCall;
			pfnInet(pfn, pStack, nSizeArgs);
		}
	}

	return nRet;
}

int CHttpServer::CountParams(LPCTSTR pszCommandLine, int& nCount)
{
	BOOL bInQuote = FALSE;
	BOOL bInSpace = TRUE;
	LPCTSTR pszWalker = pszCommandLine;
	int nRetCode = callOK;

	nCount = 0;
	if (pszCommandLine != NULL)
	{
		while (*pszWalker != '\0')
		{
			if (bInSpace)
			{
				// this is invalid syntax
				ISAPIASSERT(*pszWalker != '\'');
				if (*pszWalker == '\'')
				{
					nRetCode = callMissingQuote;
					break;
				}

				if (!_istspace(*pszWalker))
				{
					nCount++;
					bInSpace = FALSE;
				}
			}
			else
			{
				if (*pszWalker == '\'')
					bInQuote = !bInQuote;
				else if (!bInQuote &&
					(_istspace(*pszWalker) || *pszWalker == m_cTokenDelimiter))
					bInSpace = TRUE;
			}

			pszWalker++;
		}

		// can't have only whitespace
		if (nCount == 0 && bInSpace)
		{
			nRetCode = callMissingParams;
			ISAPIASSERT(nCount > 0 || !bInSpace);
		}
		// unclosed quoted string?
		else if (bInQuote)
		{
			nRetCode = callMissingQuote;
			ISAPIASSERT(!bInQuote);
		}
	}

	return nRetCode;
}

int CHttpServer::ParseDefaultParams(AFX_PARSEMAP_ENTRY* pParams,
	int nParams, AFX_PARSEMAP_ENTRY_PARAMS*& pBlock, const BYTE* pbParams)
{
	int nRet = callOK;

	LPSTR pszWalker;
	BOOL bInQuote;
	BOOL bInSpace;
	BOOL bInEquals;
	BOOL bMandatory = TRUE;

	// only if we haven't done it already

	if (pParams->pszFnName == NULL)
	{
		AFX_PARSEMAP_ENTRY_PARAMS* pParBlock = NULL;
		ISAPIASSERT(pParams->pszParamInfo == NULL);

		// can't have empty param string
		ISAPIASSERT(*pParams->pszArgs != '\0');

		if (*pParams->pszArgs != '\0')
		{
			pParBlock = new AFX_PARSEMAP_ENTRY_PARAMS;
			pBlock = pParBlock;
			memset(pParBlock, 0, sizeof(AFX_PARSEMAP_ENTRY_PARAMS));
			pParams->pszFnName = (LPTSTR) pParBlock;

			// start by finding how many parameters we have
			nRet = CountParams(pParams->pszArgs, pParBlock->nParams);
			if (nRet == callOK)
				pParams->pszParamInfo = _tcsdup(pParams->pszArgs);
		}

		if (pParBlock == NULL || nRet != callOK)
		{
			if (nRet == callOK)
				nRet = callMissingParams;
			goto CleanUp;
		}

		// wrong number of parameters?
		if (nParams != pParBlock->nParams)
		{
			nRet = callBadParamCount;
			ISAPIASSERT(nParams == pParBlock->nParams);
		}
		// it's a winner!
		else
		{
			pParBlock->ppszInfo =
				new LPTSTR[pParBlock->nParams *2];
			pParBlock->ppszDefaults =
				new BYTE[pParBlock->nParams * sizeof(double)];
			pParBlock->ppszValues =
				new BYTE[pParBlock->nParams * sizeof(double)];

			bInQuote = FALSE;
			bInSpace = TRUE;
			bInEquals = FALSE;
			int nStorage = 0;

			for (pszWalker = pParams->pszParamInfo;
				*pszWalker != '\0'; pszWalker++)
			{
				if (bInSpace)
				{
					// this is invalid syntax
					ISAPIASSERT(*pszWalker != '\'' && *pszWalker != '=');
					if (*pszWalker == '\'' || *pszWalker == '=')
					{
						nRet = callMissingQuote;
						break;
					}

					if (!_istspace(*pszWalker))
					{
						pParBlock->ppszInfo[nStorage++] = pszWalker;
						bInSpace = FALSE;
					}
				}
				else
				{
					if (bInEquals)
					{
						if (_istspace(*pszWalker) && bInQuote)
							continue;

						if (*pszWalker == '\'' || _istspace(*pszWalker))
						{
							if (bInQuote || _istspace(*pszWalker))
							{
								*pszWalker = '\0';
								bInEquals = FALSE;
								bInSpace = TRUE;
								bInQuote = FALSE;
							}
							else
							{
								pParBlock->ppszInfo[nStorage-1]++;
								bInQuote = TRUE;
							}
						}
					}
					else
					{
						// parameter with no default
						if (_istspace(*pszWalker))
						{
							// can't have required param after optional params
							ISAPIASSERT(bMandatory);
							if (!bMandatory)
							{
								nRet = callBadParam;
								goto CleanUp;
							}

							*pszWalker = '\0';
							bInSpace = TRUE;
							pParBlock->ppszInfo[nStorage++] = NULL;
						}
						// end of parameter name with default
						else if (*pszWalker == '=')
						{
							bMandatory = FALSE;
							bInEquals = TRUE;
							*pszWalker = '\0';
							pParBlock->ppszInfo[nStorage++] = pszWalker+1;
						}
						// bad syntax--quote in param name
						else if (*pszWalker == '\'')
						{
							ISAPIASSERT(*pszWalker != '\'');
							nRet = callMissingQuote;
							break;
						}
					}
				}
			}

			// handle case of no default for final param
			if (nStorage & 1)
				pParBlock->ppszInfo[nStorage] = NULL;

			int nIndex;
			for (nIndex = 0; nIndex < pParBlock->nParams; nIndex++)
			{
				if (pParBlock->ppszInfo[2*nIndex+1] != NULL)
#ifndef _SHADOW_DOUBLES
					StoreStackParameter(
						&pParBlock->ppszDefaults[sizeof(double) * nIndex],
						pbParams[nIndex], pParBlock->ppszInfo[2*nIndex+1]);
#else
					StoreStackParameter(
						&pParBlock->ppszDefaults[sizeof(double) * nIndex],
						pbParams[nIndex], pParBlock->ppszInfo[2*nIndex+1],
						0, FALSE);
#endif
				else
					pParBlock->nRequired++;
			}
		}
	}

CleanUp:
	return nRet;
}


// push arguments on stack appropriate for C++ call (compiler dependent)
#ifndef _SHADOW_DOUBLES
int CHttpServer::PushDefaultStackArgs(BYTE* pStack,
	CHttpServerContext* pCtxt,
	const BYTE* pbParams, LPTSTR pszParams,
	AFX_PARSEMAP_ENTRY_PARAMS* pDefParams)
#else
int CHttpServer::PushDefaultStackArgs(BYTE* pStack,
	CHttpServerContext* pCtxt,
	const BYTE* pbParams, LPTSTR pszParams,
	AFX_PARSEMAP_ENTRY_PARAMS* pDefParams, int nSizeArgs)
#endif
{
	ISAPIASSERT(pStack != NULL);

	LPTSTR pszCurParam = NULL;
	int nExplicit = 0;
	LPBYTE pFlags;
	int nPushedExplicit = 0;
	int nRetVal = callOK;
	LPTSTR pszLineEnd;
	BYTE*   ppszValues;     // pointers to coerced actual values

	// keep a list of flags to know what's pushed and what's not
	pFlags = new BYTE[pDefParams->nParams];
	memset(pFlags, 0, pDefParams->nParams);

	// C++ member functions use the __thiscall convention, where parameters
	//  are pushed last to first.  Assuming the stack grows down, this means
	//  that the first parameter is at the lowest memory address in the
	//  stack frame and the last parameter is at the highest address.

	// push the 'this' pointer

	*(_STACK_PTR*)pStack = (_STACK_PTR)this;
	pStack += sizeof(_STACK_PTR);

	// push our context pointer

	*(_STACK_PTR*)pStack = (_STACK_PTR)pCtxt;
	pStack += sizeof(_STACK_PTR);

	// copy the default argument list to the usable argument list
	ppszValues = new BYTE[pDefParams->nParams * sizeof(double)];
	memcpy(ppszValues, pDefParams->ppszDefaults,
		sizeof(double) * pDefParams->nParams);

	// push the arguments, if explicitly supplied

	if (pszParams != NULL)
	{
		pszLineEnd = pszParams + lstrlen(pszParams);

		TCHAR szTokens[2];
		szTokens[0] = m_cTokenDelimiter;
		szTokens[1] = '\0';

		ISAPIASSERT(pbParams != NULL);
		for (const BYTE* pb = pbParams; *pb != '\0'; ++pb)
		{
			if (*pb == IT_EMPTY)
			{
				// can't have ITS_EMPTY with other types!
				ISAPIASSERT(pb == pbParams);
				break;
			}

			if (pszParams == NULL)
				break;
			pszCurParam = _tcstok(pszParams, szTokens);
			if (pszCurParam == NULL)
				break;

			// does this param have a name?
			LPTSTR pszValue = _tcschr(pszCurParam, '=');
			if (pszValue != NULL)
			{
				*pszValue++ = '\0';

				// find the parameter in our param block

				int nIndex;
				BOOL bFound = FALSE;
				for (nIndex = 0; nIndex < pDefParams->nParams; nIndex++)
				{
					if (lstrcmpi(pDefParams->ppszInfo[nIndex*2], pszCurParam) == 0)
					{
						bFound = TRUE;
						break;
					}
				}

				// something we don't recognize?
				if (!bFound)
				{
					nRetVal = callBadParam;
					goto CleanUp;
				}

				pszParams = pszValue + lstrlen(pszValue);
				if (pszParams != pszLineEnd)
					pszParams++;

				// if this parameter has a default and there's
				// no value for the parameter after the equal sign,
				// let the default value prevail

				if (*pszValue != '\0' ||
					pDefParams->ppszInfo[2*nIndex+1] == NULL)
				{
#ifndef _SHADOW_DOUBLES
					StoreStackParameter(
						&(ppszValues[nIndex*sizeof(double)]),
						pbParams[nIndex], pszValue);
#else
					StoreStackParameter(
						&(ppszValues[nIndex*sizeof(double)]),
						pbParams[nIndex], pszValue, 0, FALSE);
#endif

					// if this has no default, it counts as explicit, too
					if (pDefParams->ppszInfo[2*nIndex+1] == NULL)
						nExplicit++;
				}

				// if we've already pushed this parameter, or if we've
				// already pushed this many explicit params, make an error
				if (pFlags[nIndex] != 0 || nIndex < nPushedExplicit)
				{
					nRetVal = callBadParam;
					goto CleanUp;
				}
				pFlags[nIndex] = 1;
			}
			else
			{
				// not allowed to have optional params before required params
				if (nExplicit != 0)
				{
					nRetVal = callBadParam;
					goto CleanUp;
				}

				pszParams += lstrlen(pszCurParam);
				if (pszParams != pszLineEnd)
					pszParams++;

#ifndef _SHADOW_DOUBLES
				pStack = StoreStackParameter(pStack, *pb, pszCurParam);
#else
				pStack = StoreStackParameter(pStack, *pb, pszCurParam,
					nSizeArgs, TRUE);
#endif

				if (pFlags[nPushedExplicit] != 0)
				{
					nRetVal = callBadParam;
					goto CleanUp;
				}
				pFlags[nPushedExplicit] = 1;
				nPushedExplicit++;
			}
		}

		// any unused parameters?

		LPTSTR pszMoreParams;
		pszMoreParams = _tcschr(pszParams, m_cTokenDelimiter);

		if (*pb == '\0' && (pszMoreParams != NULL || *pszParams != '\0'))
		{
			nRetVal = callBadParamCount;
			goto CleanUp;
		}
	}

	// were any arguments without defaults missed?
	if (nPushedExplicit + nExplicit < pDefParams->nRequired)
	{
		nRetVal = callBadParamCount;
	}
	else if (nPushedExplicit < pDefParams->nParams)
	{
		int nIndex;
		for (nIndex = nPushedExplicit; nIndex < pDefParams->nParams; nIndex++)
		{
#ifndef _SHADOW_DOUBLES
			pStack = StoreRawStackParameter(pStack,
				pbParams[nIndex],
				&(ppszValues[nIndex*sizeof(double)]));
#else
			pStack = StoreRawStackParameter(pStack,
				pbParams[nIndex],
				&(ppszValues[nIndex*sizeof(double)]), 0);
#endif
		}
	}

CleanUp:
	if (pFlags != NULL)
		delete [] pFlags;
	if (ppszValues != NULL)
		delete [] ppszValues;
	return nRetVal;
}


// push arguments on stack appropriate for C++ call (compiler dependent)
#ifndef _SHADOW_DOUBLES
int CHttpServer::PushStackArgs(BYTE* pStack, CHttpServerContext* pCtxt,
	const BYTE* pbParams, LPTSTR pszParams)
#else
int CHttpServer::PushStackArgs(BYTE* pStack, CHttpServerContext* pCtxt,
	const BYTE* pbParams, LPTSTR pszParams, UINT nSizeArgs)
#endif
{
	LPTSTR pszCurParam = NULL;
	ISAPIASSERT(pStack != NULL);

	// C++ member functions use the __thiscall convention, where parameters
	//  are pushed last to first.  Assuming the stack grows down, this means
	//  that the first parameter is at the lowest memory address in the
	//  stack frame and the last parameter is at the highest address.

	// push the 'this' pointer

	*(_STACK_PTR*)pStack = (_STACK_PTR)this;
	pStack += sizeof(_STACK_PTR);

	// push our context pointer

	*(_STACK_PTR*)pStack = (_STACK_PTR)pCtxt;
	pStack += sizeof(_STACK_PTR);

	// push the arguments (first to last, low address to high address)

	TCHAR szTokens[2];
	szTokens[0] = m_cTokenDelimiter;
	szTokens[1] = '\0';
	const BYTE* pb;
	int nRetCode = callOK;

	if (pszParams != NULL && *pbParams == IT_EMPTY)
		nRetCode = callBadParamCount;
	else if (pszParams != NULL)
	{
		LPTSTR pszLineEnd;
		pszLineEnd = pszParams + lstrlen(pszParams);

		ISAPIASSERT(pbParams != NULL);
		for (pb = pbParams; *pb != '\0'; ++pb)
		{
			if (*pb == IT_EMPTY)
			{
				// can't have ITS_EMPTY with other types!
				ISAPIASSERT(pb == pbParams);
				if (pb != pbParams)
					nRetCode = callBadParam;
				break;
			}

			if (*pb == IT_RAW)
			{
				// can't have ITS_RAW with other types!
				ISAPIASSERT(pb == pbParams);
				if (pb != pbParams)
					nRetCode = callBadParam;
				else
				{
					BYTE* pbParam = (BYTE*) &pszParams;
#ifndef _SHADOW_DOUBLES
					pStack = StoreRawStackParameter(pStack, IT_PSTR, pbParam);
					pStack = StoreRawStackParameter(pStack, IT_I4,
						(BYTE*) &(pCtxt->m_dwBytesReceived));
#else
					pStack = StoreRawStackParameter(pStack, IT_PSTR, pbParam);
					pStack = StoreRawStackParameter(pStack, IT_I4,
						(BYTE*) &(pCtxt->m_dwBytesReceived));
#endif
				}
				return nRetCode;
			}

			if (pszParams == NULL)
				break;
			pszCurParam = _tcstok(pszParams, szTokens);
			if (pszCurParam == NULL)
				break;

			pszParams = pszCurParam + lstrlen(pszCurParam);
			if (pszParams != pszLineEnd)
				pszParams++;

#ifndef _SHADOW_DOUBLES
			pStack = StoreStackParameter(pStack, *pb, pszCurParam);
#else
			pStack = StoreStackParameter(pStack, *pb, pszCurParam, nSizeArgs, TRUE);
#endif
		}

		// check that all source arguments were consumed

		if (nRetCode == callOK)
		{
			LPTSTR pszMoreParams;
			pszMoreParams = _tcschr(pszParams, m_cTokenDelimiter);

			if (*pb != '\0' && pszMoreParams == NULL)
				nRetCode = callBadParamCount;
			else if (*pb == '\0' && (pszMoreParams != NULL || *pszParams != '\0'))
				nRetCode = callBadParamCount;
		}
	}
	else
	{
		if (*pbParams != IT_EMPTY)
			nRetCode = callBadParamCount;
	}

	return nRetCode;
}

#ifndef _SHADOW_DOUBLES
BYTE* CHttpServer::StoreRawStackParameter(BYTE* pStack, BYTE nType,
	BYTE* pRawParam)
#else
BYTE* CHttpServer::StoreRawStackParameter(BYTE* pStack, BYTE nType,
	BYTE* pRawParam, int nSizeArgs)
#endif
{
	ISAPIASSERT(pStack != NULL);
	ISAPIASSERT(pRawParam != 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:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -