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

📄 extns.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
						
			// Connection header determined by fKeepConn of passed in struct
			CHttpResponse resp(this, STATUS_OK,
			                   pHeaderEx->fKeepConn ? CONN_KEEP : CONN_CLOSE);

			m_fKeepAlive = pHeaderEx->fKeepConn;
			// no body, default or otherwise (leave that to the ISAPI), but add default headers
			resp.SendResponse(pHeaderEx->pszHeader, pHeaderEx->pszStatus);
			return TRUE;
		}
		
		case HSE_APPEND_LOG_PARAMETER:
		{
			return MyStrCatA(&m_pszLogParam,(PSTR) pvBuf,",");
		}

		// HSE_REQ_GET_LOCAL_SOCKADDR and HSE_REQ_GET_REMOTE_SOCKADDR are WinCE 
		// extensions to ISAPI's.  Makes it possible for apps to retrieve
		// the SOCKADDR of either local or remote client.
		case HSE_REQ_GET_LOCAL_SOCKADDR:
		{
			return (0 == getsockname(m_socket,(PSOCKADDR)pvBuf,(int*)pdwSize));
		}

		case HSE_REQ_GET_REMOTE_SOCKADDR:
		{
			return (0 == getpeername(m_socket,(PSOCKADDR)pvBuf,(int*)pdwSize));
		}        
	}
}	

BOOL CHttpRequest::MapURLToPath(PSTR pszBuffer, PDWORD pdwSize, LPHSE_URL_MAPEX_INFO pUrlMapEx)
{
	PWSTR wszPath;
	PSTR pszURL;
	DWORD dwBufNeeded = 0;
	BOOL ret;
	PVROOTINFO pVRoot;

	wszPath = m_pWebsite->m_pVroots->URLAtoPathW(pszBuffer,&pVRoot);
	if(!wszPath) {
		// Assume failure on matching to virtual root, and not on mem alloc
		SetLastError(ERROR_INVALID_PARAMETER);
		return FALSE;
	}

	dwBufNeeded = (DWORD) WideCharToMultiByte(CP_ACP,0, wszPath, -1, pszBuffer, 0 ,0,0);

	// For MAP_EX case, we set these vars from the passed structure, else we use the raw ptrs.
	if (pUrlMapEx) {
		pszURL = pUrlMapEx->lpszPath;
		*pdwSize = MAX_PATH;
	}
	else {
		pszURL = pszBuffer;
	}

	// To keep compat with IIS, we translate "/" to "\".  We do the conversion
	// only if we're using filters or if there's enough space in the buffer.
	if (g_pVars->m_fFilters || *pdwSize >= dwBufNeeded) {
		for (int i = 0; i < (int) wcslen(wszPath); i++) {
			if ( wszPath[i] == L'/')
				wszPath[i] = L'\\';
		}
	}

	if (FALSE == g_pVars->m_fFilters) {
		// We check to make sure buffer is the right size because WideToMultyByte
		// will overwrite pieces of pszURL even on failure, leaving pszURL's 
		// content invalid
		if (*pdwSize < dwBufNeeded) {
			SetLastError(ERROR_INSUFFICIENT_BUFFER);
			ret = FALSE;
		}
		else {
			MyW2A(wszPath, pszURL, *pdwSize);
			ret = TRUE;
		}
		*pdwSize = dwBufNeeded;  
	}
	else {
		// for EX case, put original URL as optional 5th parameter.
		ret = FilterMapURL(pszURL, wszPath, pdwSize,dwBufNeeded, pUrlMapEx ? pszBuffer : NULL);
	}	

	if (ret && pUrlMapEx) {
		pUrlMapEx->cchMatchingPath = *pdwSize - 1;		// don't count \0
		pUrlMapEx->cchMatchingURL  = strlen(pszBuffer);
		pUrlMapEx->dwFlags = pVRoot->dwPermissions;
	}

	MyFree(wszPath);
	return ret;
}


void CISAPI::Unload(PWSTR wszDLLName) { 
	if(m_pfnTerminate) {
		__try {
			if(SCRIPT_TYPE_FILTER == m_scriptType)
				((PFN_TERMINATEFILTER)m_pfnTerminate)(HSE_TERM_MUST_UNLOAD);
			else if (SCRIPT_TYPE_EXTENSION == m_scriptType)
				((PFN_TERMINATEEXTENSION)m_pfnTerminate)(HSE_TERM_MUST_UNLOAD);
			else if (SCRIPT_TYPE_ASP == m_scriptType)
				((PFN_TERMINATEASP)m_pfnTerminate)();

		}
		__except(ReportFault(GetExceptionInformation(),0), EXCEPTION_EXECUTE_HANDLER) {
			DWORD dwExceptionCode = SCRIPT_TYPE_FILTER == m_scriptType ?
									IDS_HTTPD_FILT_EXCEPTION : IDS_HTTPD_EXT_EXCEPTION;
			PWSTR wszFunction =     SCRIPT_TYPE_FILTER == m_scriptType ?
									L"TerminateFilter" : L"TerminateExtension"; 
									
			DEBUGMSG(ZONE_ERROR, (L"HTTPD: TerminateExtension faulted\r\n"));
			g_pVars->m_pLog->WriteEvent(dwExceptionCode,wszDLLName ? wszDLLName : m_wszDLLName,
										GetExceptionCode(),wszFunction,GetLastError());
		}
	}
	MyFreeLib(m_hinst); 
	m_hinst = NULL;
	m_pfnTerminate = NULL;
}


// To see if two file names are equal,
// do a normal string compare with the difference that "/" and "\" are treated
// as equiavalents.  (They may not be same in two passed variables due to the
// way web server does VRoot name mapping).

// Format like wcsicmp, returns 0 if strings are equal.
int PathNameCompare(WCHAR *src, WCHAR *dst) {
	WCHAR f,l;
	BOOL fSlashMatch;

	do  {
		fSlashMatch = (*dst == L'/' || *dst == L'\\') && (*src == L'/' || *src == L'\\');
		f = towlower(*dst++);
		l = towlower(*src++);
	} while (f && ((f == l) || fSlashMatch));

	if (fSlashMatch)
		return 0;

	return (int)(f - l);
}

int PathNameCompareN(WCHAR *src, WCHAR *dst, int len) {
	WCHAR f,l;
	BOOL fSlashMatch;

	do  {
		fSlashMatch = (*dst == L'/' || *dst == L'\\') && (*src == L'/' || *src == L'\\');
		f = towlower(*dst++);
		l = towlower(*src++);
	} while (f && ((f == l) || fSlashMatch) && --len);

	if (fSlashMatch)
		return 0;

	return (int)(f - l);
}


BOOL IsScriptInNoUnloadList(WCHAR *szDLLName) {
	for (DWORD i = 0; i < g_pVars->m_scriptNoUnload.dwEntries; i++) {
		if (0 == PathNameCompare(g_pVars->m_scriptNoUnload.ppszNoUnloadEntry[i],szDLLName))
			return TRUE;
	}
	return FALSE;
}

BOOL CISAPI::LoadExports(HINSTANCE hInst, BOOL fVerifyOnly) {
	BOOL fRet = FALSE;

	if (SCRIPT_TYPE_ASP == m_scriptType) {
		m_pfnHttpProc  = GetProcAddress(hInst, CE_STRING("ExecuteASP"));
		m_pfnTerminate = GetProcAddress(hInst, CE_STRING("TerminateASP"));

		fRet = (m_pfnHttpProc && m_pfnTerminate);
		goto done;
	}

	if (SCRIPT_TYPE_EXTENSION == m_scriptType) {
		m_pfnGetVersion = GetProcAddress(hInst, CE_STRING("GetExtensionVersion"));
		m_pfnHttpProc 	= GetProcAddress(hInst, CE_STRING("HttpExtensionProc"));
		m_pfnTerminate  = GetProcAddress(hInst, CE_STRING("TerminateExtension"));
	}
	else if (SCRIPT_TYPE_FILTER == m_scriptType) {
		m_pfnGetVersion = GetProcAddress(hInst, CE_STRING("GetFilterVersion"));
		m_pfnHttpProc 	= GetProcAddress(hInst, CE_STRING("HttpFilterProc"));
		m_pfnTerminate  = GetProcAddress(hInst, CE_STRING("TerminateFilter"));
	}
	else {
		DEBUGCHK(0); // unknown script type
	}
	
	fRet = (m_pfnHttpProc && m_pfnGetVersion);

done:
	if (fVerifyOnly) {
		// NULL out proc ptrs since we'll be unloading DLL data file.
		m_pfnGetVersion = m_pfnHttpProc = m_pfnTerminate = NULL;
	}

	return fRet;
}

BOOL CISAPI::Load(PWSTR wszPath)  {
	// First we load the ISAPI as a LOAD_LIBRARY_AS_DATAFILE and verify
	// that it has the proper exports for given ISAPI.  We do this
	// because it guarantees that DllMain() won't be called until we're
	// sure we really are dealing with an ISAPI extension.

	HINSTANCE hLibData = LoadLibraryEx(wszPath,NULL,DONT_RESOLVE_DLL_REFERENCES);
	if (!hLibData) {
		DEBUGMSG(ZONE_ERROR,(L"HTTPD: LoadLibraryEx(%s) fails.  GLE=0x%08x\r\n",wszPath,GetLastError()));
		return FALSE;
	}

	if (! LoadExports(hLibData,TRUE)) {
		FreeLibrary(hLibData);
		return FALSE;
	}
	FreeLibrary(hLibData);

	// Now load the DLL "for real"
	m_hinst = LoadLibrary(wszPath); 
	if(!m_hinst) 
		return FALSE;

	if (SCRIPT_TYPE_EXTENSION == m_scriptType || SCRIPT_TYPE_ASP == m_scriptType)
		m_fCanTimeout = ! (IsScriptInNoUnloadList(wszPath));

	if (! LoadExports(m_hinst,FALSE))
		goto done;

	__try {
		// call GetVersion immediately after load on extensions and Filters, but not ASP
		// if it's a filter we need to do some flags work first
		if(SCRIPT_TYPE_FILTER == m_scriptType) {
			HTTP_FILTER_VERSION vFilt;
			// IIS ignores ISAPI version info, so do we.

			PREFAST_ASSERT(m_pfnGetVersion != NULL); // LoadExports verifies that m_pfnGetVersion != NULL.
			((PFN_GETFILTERVERSION)m_pfnGetVersion)(&vFilt); 
			dwFilterFlags = vFilt.dwFlags;

			// client didn't set the prio flags, assign them to default
			// If they set more than one prio we use the highest + ignore others
			if (0 == (dwFilterFlags & SF_NOTIFY_ORDER_MASK)) {
				dwFilterFlags |= SF_NOTIFY_ORDER_DEFAULT;
			}
			// If the Filter set neither SF_NOTIFY_SECURE_PORT nor SF_NOTIFY_NONSECURE_PORT
			// then we notify them for both.

			if (0 == (dwFilterFlags & (SF_NOTIFY_SECURE_PORT | SF_NOTIFY_NONSECURE_PORT))) {
				dwFilterFlags |= SF_NOTIFY_SECURE_PORT | SF_NOTIFY_NONSECURE_PORT;
			}
		}
		else if (SCRIPT_TYPE_EXTENSION == m_scriptType) {
			HSE_VERSION_INFO 	vExt;
			// IIS ignores ISAPI version info, so do we.
			((PFN_GETEXTENSIONVERSION)m_pfnGetVersion)(&vExt); 
		}

		return TRUE;
	}
	__except(ReportFault(GetExceptionInformation(),0), EXCEPTION_EXECUTE_HANDLER) {
		DWORD dwExceptionCode = SCRIPT_TYPE_FILTER == m_scriptType ?
								IDS_HTTPD_FILT_EXCEPTION : IDS_HTTPD_EXT_EXCEPTION;
		PWSTR wszFunction =     SCRIPT_TYPE_FILTER == m_scriptType ?
								L"GetFilterVersion" : L"GetExtensionVersion"; 

		DEBUGMSG(ZONE_ERROR, (L"HTTPD: GetExtensionVersion faulted\r\n"));
		g_pVars->m_pLog->WriteEvent(dwExceptionCode,wszPath,GetExceptionCode(),wszFunction,GetLastError());
	}
	// fall through to error

done:
	m_pfnGetVersion = 0;
	m_pfnHttpProc = 0;
	m_pfnTerminate = 0;
	MyFreeLib(m_hinst);
	m_hinst = 0;
	return FALSE;
}


//**********************************************************************
// ISAPI Caching functions
//**********************************************************************
HINSTANCE CISAPICache::Load(PWSTR wszDLLName, CISAPI **ppISAPI, SCRIPT_TYPE st) {
	DEBUG_CODE_INIT;
	BOOL ret = FALSE;
	PISAPINODE pTrav = NULL;

	EnterCriticalSection(&m_CritSec);

	for (pTrav = m_pHead; pTrav != NULL; pTrav = pTrav->m_pNext) {
		if ( 0 == wcsicmp(pTrav->m_pISAPI->m_wszDLLName, wszDLLName)) {
			DEBUGMSG(ZONE_ISAPI,(L"HTTPD: Found ISAPI dll in cache, name = %s, cur ref count = %d\r\n",
								  wszDLLName, pTrav->m_pISAPI->m_cRef));
			break;
		}
	}

	if (NULL == pTrav) 	{
		DEBUGMSG(ZONE_ISAPI,(L"HTTPD: ISAPI dll name = %s not found in cache, creating new entry\r\n",wszDLLName));
		if (NULL == (pTrav = MyAllocNZ(ISAPINODE)))
			myleave(1200);

		if (NULL == (pTrav->m_pISAPI = new CISAPI(st)))
			myleave(1201);
			
		if (NULL == (pTrav->m_pISAPI->m_wszDLLName = MySzDupW(wszDLLName)))
			myleave(1202);

		if (! pTrav->m_pISAPI->Load(wszDLLName))
			myleave(1203);

		pTrav->m_pNext = m_pHead;
		m_pHead = pTrav;			
	}
	pTrav->m_pISAPI->m_cRef++;


	*ppISAPI = pTrav->m_pISAPI;
	ret = TRUE;
done:
	if (!ret) {
		if (pTrav && pTrav->m_pISAPI) {
			MyFree(pTrav->m_pISAPI->m_wszDLLName);
			delete pTrav->m_pISAPI;
		}
			
		MyFree(pTrav);
	}
		
	DEBUGMSG_ERR(ZONE_ISAPI,(L"HTTPD: CISAPICache::LoadISAPI failed, err = %d, GLE = 0x%08x\r\n",err,GetLastError()));
	LeaveCriticalSection(&m_CritSec);

	if (ret)
		return pTrav->m_pISAPI->m_hinst;
		

⌨️ 快捷键说明

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