예제 #1
0
int CHttpServer::CallFunction(CHttpServerContext* pCtxt,
	LPTSTR pszQuery, LPTSTR pszCommand)
{
	int nRet;

	AFX_PARSEMAP_ENTRY* pParams;
	const AFX_PARSEMAP* pMap;
	const AFX_PARSEMAP_ENTRY* pFn;

	ISAPIASSERT(pCtxt->m_pStream == NULL);
	pCtxt->m_pStream = ConstructStream();
	if (pCtxt->m_pStream == NULL)
		nRet = callNoStream;
	else
	{
		ISAPIASSERT(pszQuery != NULL);
		if (pszQuery == NULL)
			nRet = callBadCommand;
		else
		{
			LPTSTR pszMethod;
			LPTSTR pszParams;

			// did the user specify a command via "MfcISAPICommand"?

			LPTSTR pszHiddenCommand = _tcschr(pszQuery, '=');
			if (pszHiddenCommand != NULL)
			{
				*pszHiddenCommand = '\0';

				// is it there?

				if (_tcsicmp(pszQuery, _T("MfcISAPICommand")) == 0)
				{
					// did they have a method, too?

					pszMethod = pszHiddenCommand+1;
					if (*pszMethod == '\0')
						pszParams = pszMethod;
					else
					{
						pszParams = _tcschr(pszMethod, m_cTokenDelimiter);
						if (pszParams != NULL && *pszParams != '\0')
							*pszParams++ = '\0';
					}

					// if we find it, we can call it

					pFn = LookUp(pszMethod, pMap, pParams);
					if (pFn != NULL)
						goto MakeTheCall;
				}

				// we didn't find the command, or we didn't have
				// "MfcISAPICommand", so we'll try and process things
				// normally...

				*pszHiddenCommand = '=';
			}

			if (pszCommand == NULL)
			{
				// got something via a GET method
				// is the first thing a parameter or a command?

				LPTSTR pszEquals;
				LPTSTR pszQMark;

				pszParams = _tcschr(pszQuery, m_cTokenDelimiter);
				pszQMark = _tcschr(pszQuery, '?');

				// Parameters start at the first delimiter

				if (pszParams == NULL || (pszQMark != NULL && (pszQMark < pszParams)))
				{
					pszParams = pszQMark;

					// if the command ends in question mark
					// and nothing else, ignore it
					if (pszQMark != NULL && pszQMark[1] == '\0')
					{
						*pszQMark = '\0';
						pszParams = NULL;
					}
				}

				// Does an equals sign show up before the first delimiter?

				pszEquals = _tcschr(pszQuery, '=');
				if (pszEquals == NULL || pszEquals > pszParams)
				{
					// It might be a command. If it isn't blank,
					// try and find it in the parameter map--if
					// we can't, then assume it is a parameter.

					pszMethod = pszQuery;
					if (*pszMethod != '\0')
					{
						TCHAR cTemp;
						if (pszParams != NULL)
						{
							cTemp = *pszParams;
							*pszParams++ = '\0';
						}

						pFn = LookUp(pszMethod, pMap, pParams);
						if (pFn != NULL)
							goto MakeTheCall;

						if (pszParams != NULL)
							*--pszParams = cTemp;
					}
				}

				// we can be sure it's a parameter
				if (pszQMark == NULL || pszQMark >= pszParams)
				{
					// default command, params as supplied
					pszMethod = NULL;
					pszParams = pszQuery;
				}
				else
				{
					pszMethod = pszQuery;
					*pszQMark++ = '\0';
					pszParams = pszQMark;
				}
			}
			else
			{
				// with a POST, the verb arrives seperately
				pszMethod = pszCommand;
				pszParams = pszQuery;
			}

			// is it a default verb?
			if (pszMethod != NULL && _tcslen(pszMethod) == 0)
				pszMethod = NULL;

			// is it a useless parameter?
			if (pszParams != NULL && _tcslen(pszParams) == 0)
				pszParams = NULL;

			pFn = LookUp(pszMethod, pMap, pParams);

MakeTheCall:
			if (pFn == NULL)
				nRet = callBadCommand;
			else
			{
				pCtxt->m_pStream->InitStream();
				nRet = CallMemberFunc(pCtxt, pFn, pParams, pszParams);
			}
		}
	}

	return nRet;
}
예제 #2
0
BOOL CCmdTarget::OnEvent(UINT idCtrl, AFX_EVENT* pEvent,
	AFX_CMDHANDLERINFO* pHandlerInfo)
{
	HRESULT hResult = S_OK;
	UINT uArgError = (UINT)-1;    // no error yet
	const AFX_EVENTSINKMAP_ENTRY* pEntry = GetEventSinkEntry(idCtrl, pEvent);

	// no handler for this event
	if (pEntry == NULL)
		return FALSE;

	if (pHandlerInfo != NULL)
	{
		// just fill in the information, don't do it
		pHandlerInfo->pTarget = this;
		switch (pEvent->m_eventKind)
		{
		case AFX_EVENT::event:
		case AFX_EVENT::propRequest:
			pHandlerInfo->pmf = pEntry->dispEntry.pfn;
			break;

		case AFX_EVENT::propChanged:
			pHandlerInfo->pmf = pEntry->dispEntry.pfnSet;
			break;

		default:
			ASSERT(FALSE);  // bogus value for pEvent->m_eventKind
		}

		return (pHandlerInfo->pmf != NULL);
	}

	BOOL bRange = (pEntry->nCtrlIDLast != (UINT)-1);
	BOOL bHandled = FALSE;

	TRY
	{
		switch (pEvent->m_eventKind)
		{
		case AFX_EVENT::event:
			// do standard method call
			VARIANT var;
			AfxVariantInit(&var);

			DISPPARAMS dispparams;
			dispparams.rgvarg = NULL;

			if (bRange)
			{
				memcpy(&dispparams, pEvent->m_pDispParams, sizeof(DISPPARAMS));
				dispparams.rgvarg = new VARIANT[++dispparams.cArgs];
				memcpy(dispparams.rgvarg, pEvent->m_pDispParams->rgvarg,
					sizeof(VARIANT) * (dispparams.cArgs-1));
				VARIANT* pvarID = &dispparams.rgvarg[dispparams.cArgs-1];
				V_VT(pvarID) = VT_I4;
				V_I4(pvarID) = idCtrl;
			}

			hResult = CallMemberFunc(&pEntry->dispEntry, DISPATCH_METHOD, &var,
				(bRange ? &dispparams : pEvent->m_pDispParams), &uArgError);
			ASSERT(FAILED(hResult) || (V_VT(&var) == VT_BOOL));
			bHandled = V_BOOL(&var);

			if (bRange)
				delete [] dispparams.rgvarg;

			break;

		case AFX_EVENT::propChanged:
			{
				if (bRange)
				{
					PFN_CHANGED_RANGE pfn = (PFN_CHANGED_RANGE)pEntry->dispEntry.pfnSet;
					bHandled = (this->*pfn)(idCtrl);
				}
				else
				{
					PFN_CHANGED pfn = (PFN_CHANGED)pEntry->dispEntry.pfnSet;
					bHandled = (this->*pfn)();
				}

				hResult = S_OK;
			}
			break;

		case AFX_EVENT::propRequest:
			{
				BOOL bAllow = TRUE;

				if (bRange)
				{
					PFN_REQUEST_RANGE pfn = (PFN_REQUEST_RANGE)pEntry->dispEntry.pfn;
					bHandled = (this->*pfn)(idCtrl, &bAllow);
				}
				else
				{
					PFN_REQUEST pfn = (PFN_REQUEST)pEntry->dispEntry.pfn;
					bHandled = (this->*pfn)(&bAllow);
				}

				hResult = bAllow ? S_OK : S_FALSE;
			}
			break;

		case AFX_EVENT::propDSCNotify:
			{
				BOOL bAllow = TRUE;

				if (bRange)
				{
					PFN_DSCNOTIFY_RANGE pfn = (PFN_DSCNOTIFY_RANGE)pEntry->dispEntry.pfn;
					bHandled = (this->*pfn)(idCtrl, pEvent->m_nDSCState,
						pEvent->m_nDSCReason, &bAllow);
				}
				else
				{
					PFN_DSCNOTIFY pfn = (PFN_DSCNOTIFY)pEntry->dispEntry.pfn;
					bHandled = (this->*pfn)(pEvent->m_nDSCState,
						pEvent->m_nDSCReason, &bAllow);
				}

				hResult = bAllow ? S_OK : S_FALSE;
			}
			break;

		default:
			ASSERT(FALSE);  // bogus value for pEvent->m_eventKind
		}
	}
	CATCH_ALL(e)
	{
		if (pEvent->m_pExcepInfo != NULL)
		{
			// fill exception with translation of MFC exception
			COleDispatchException::Process(pEvent->m_pExcepInfo, e);
		}
		DELETE_EXCEPTION(e);
		hResult = DISP_E_EXCEPTION;
	}
	END_CATCH_ALL

	// fill error argument if one is available
	if (FAILED(hResult) && pEvent->m_puArgError != NULL && uArgError != -1)
		*pEvent->m_puArgError = uArgError;

	// fill result code
	pEvent->m_hResult = hResult;

	return bHandled;
}