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

📄 extns.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	return NULL;
}


// fRemoveAll = TRUE  ==> remove all ISAPI's, we're shutting down
//   		  = FALSE ==> only remove ones who aren't in use and whose time has expired

void CISAPICache::RemoveUnusedISAPIs(BOOL fRemoveAll) {
	PISAPINODE pTrav   = NULL;
	PISAPINODE pFollow = NULL;	
	PISAPINODE pDelete = NULL;
	SYSTEMTIME st;
	__int64 ft;

	EnterCriticalSection(&m_CritSec);
	GetSystemTime(&st);
	SystemTimeToFileTime(&st,(FILETIME*) &ft);

	// Figure out what time it was g_pVars->m_dwCacheSleep milliseconds ago.
	// Elements that haven't been used since then and that have no references
	// are deleted.

	ft -= FILETIME_TO_MILLISECONDS * g_pVars->m_dwCacheSleep;
	

	for (pTrav = m_pHead; pTrav != NULL; ) {
		if (fRemoveAll ||
		   (pTrav->m_pISAPI->m_fCanTimeout && pTrav->m_pISAPI->m_cRef == 0 && pTrav->m_pISAPI->m_ftLastUsed < ft))
		{
			DEBUGMSG(ZONE_ISAPI,(L"HTTPD: Freeing unused ISAPI Dll %s\r\n",pTrav->m_pISAPI->m_wszDLLName));
	
			pTrav->m_pISAPI->Unload();	
			delete pTrav->m_pISAPI;

			if (pFollow)
				pFollow->m_pNext = pTrav->m_pNext;
			else
				m_pHead = pTrav->m_pNext;

			pDelete = pTrav;
			pTrav = pTrav->m_pNext;
			MyFree(pDelete);
		}
		else {
			if (pTrav->m_pISAPI->m_cRef == 0)
				pTrav->m_pISAPI->CoFreeUnusedLibrariesIfASP();
				
			pFollow = pTrav;
			pTrav = pTrav->m_pNext;
		}
	}

	LeaveCriticalSection(&m_CritSec);
}

//
// Script Mapping code.  Using script mapping causes all files of extension .xxx to
// be mapped to an ISAPI dll or ASP, as specified in the registry.
// 
void RemoveScriptNodes(PSCRIPT_MAP_NODE pScriptNodes, DWORD dwEntries) {
	for (DWORD i = 0; i < dwEntries; i++) {
		MyFree(pScriptNodes[i].wszFileExtension);
		MyFree(pScriptNodes[i].wszISAPIPath);
	}
	MyFree(pScriptNodes);
}

void RemoveScriptNoUnloadList(WCHAR **szArray, DWORD dwEntries) {
	for (DWORD i = 0; i < dwEntries; i++)
		MyFree(szArray[i]);

	MyFree(szArray);
}

#define MAX_NO_UNLOAD_ENTRIES     10000

void InitScriptNoUnloadList(PSCRIPT_NOUNLOAD pNoUnloadList) {
	CReg reg(HKEY_LOCAL_MACHINE,RK_SCRIPT_NOUNLOAD);
	DWORD dwRegValues;
	DWORD dwEntries = 0;

	WCHAR szScriptName[MAX_PATH];
	WCHAR szBuf[MAX_PATH];
	WCHAR **szScriptNames;

	if (!reg.IsOK() || (0 == (dwRegValues = reg.NumValues()))) {
		DEBUGMSG(ZONE_ISAPI,(L"HTTPD: No scripts to keep permanently loaded listed!\r\n"));
		return;
	}

	if (dwRegValues > MAX_NO_UNLOAD_ENTRIES) {
		DEBUGMSG(ZONE_ERROR,(L"HTTPD: # registry entries in no-unload list is %d - too large\r\n",dwRegValues));
		DEBUGCHK(0);
		return;
	}

	if (NULL == (szScriptNames = MyRgAllocZ(WCHAR*,dwRegValues))) {
		DEBUGMSG(ZONE_ERROR,(L"HTTP: Out of memory, GLE=0x%08x\r\n",GetLastError()));
		return;
	}

	for (DWORD j = 0; j < dwRegValues; j++) {
		if (! reg.EnumValue(szBuf,CCHSIZEOF(szBuf),szScriptName,CCHSIZEOF(szScriptName)) || wcslen(szScriptName) == 0)
			continue;

		if (NULL == (szScriptNames[dwEntries] = MySzDupW(szScriptName))) {
			DEBUGMSG(ZONE_ERROR,(L"HTTP: Out of memory, GLE=0x%08x\r\n",GetLastError()));
			RemoveScriptNoUnloadList(szScriptNames,dwEntries);
			return;
		}
		dwEntries++;
	}
	DEBUGCHK(dwEntries <= dwRegValues);

	if (dwEntries == 0)  {
		DEBUGMSG(ZONE_ISAPI,(L"HTTPD: No ScriptMaps defined!\r\n"));
		MyFree(szScriptNames);
		return;
	}

	pNoUnloadList->dwEntries          = dwEntries;
	pNoUnloadList->ppszNoUnloadEntry  = szScriptNames;
}

void InitScriptMapping(PSCRIPT_MAP pTable) {
	CReg reg(HKEY_LOCAL_MACHINE,RK_SCRIPT_MAP);
	DWORD dwRegValues;
	DWORD dwEntries = 0;
	PSCRIPT_MAP_NODE pScriptNodes = NULL;

	WCHAR szFileExt[MAX_PATH];
	WCHAR szPath[MAX_PATH];

	if (!reg.IsOK() || (0 == (dwRegValues = reg.NumValues()))) {
		DEBUGMSG(ZONE_ISAPI,(L"HTTPD: No ScriptMaps defined!\r\n"));
		return;
	}

	if (NULL == (pScriptNodes = MyRgAllocZ(SCRIPT_MAP_NODE,dwRegValues))) {
		DEBUGMSG(ZONE_ERROR,(L"HTTP: Out of memory, GLE=0x%08x\r\n",GetLastError()));
		return;
	}


	// Registry value name specifies the file extension, value is the ISAPI's path.
	PREFAST_SUPPRESS(12009,"dwRegValues is number of registry values from a protected reg key and is always small");
	for (DWORD j = 0; j < dwRegValues; j++) {
		if (! reg.EnumValue(szFileExt,CCHSIZEOF(szFileExt),szPath,CCHSIZEOF(szPath)))
			continue;

		if (wcslen(szFileExt) < 2 || szFileExt[0] != L'.' || wcslen(szPath) == 0 || 0 == wcsicmp(szFileExt,L".dll")) {
			DEBUGMSG(ZONE_ERROR,(L"HTTPD: ScriptPath (fileExtension=%s, path=%s) invalid.  Must begin with '.', have at least 2 characters, may NOT be .dll\r\n",szFileExt,szPath));
			continue;
		}

		pScriptNodes[dwEntries].wszFileExtension = MySzDupW(szFileExt);

		if (wcsicmp(szPath,L"\\windows\\asp.dll") == 0)
			pScriptNodes[dwEntries].fASP = TRUE;
		else		
			pScriptNodes[dwEntries].wszISAPIPath = MySzDupW(szPath);

		if (!pScriptNodes[dwEntries].wszFileExtension || (!pScriptNodes[dwEntries].fASP && ! pScriptNodes[dwEntries].wszISAPIPath)) {
			DEBUGMSG(ZONE_ERROR,(L"HTTP: Out of memory, GLE=0x%08x\r\n",GetLastError()));
			RemoveScriptNodes(pScriptNodes,dwEntries);
			return;
		}

		dwEntries++;
	}
	DEBUGCHK(dwEntries <= dwRegValues);

	if (dwEntries == 0)  {
		DEBUGMSG(ZONE_ISAPI,(L"HTTPD: No ScriptMaps defined!\r\n"));
		MyFree(pScriptNodes);
		return;
	}

	pTable->dwEntries      = dwEntries;
	pTable->pScriptNodes   = pScriptNodes;
}

BOOL MapScriptExtension(WCHAR *wszFileExt, WCHAR **pwszISAPIPath, BOOL *pfIsASP) {
	PSCRIPT_MAP_NODE pScriptNodes = g_pVars->m_scriptMap.pScriptNodes;

	for (DWORD i = 0; i < g_pVars->m_scriptMap.dwEntries; i++) {
		if (wcsicmp(wszFileExt,pScriptNodes[i].wszFileExtension) == 0) {
			if (pScriptNodes[i].fASP)
				*pfIsASP = TRUE;
			else
				*pwszISAPIPath = pScriptNodes[i].wszISAPIPath;

			return TRUE;
		}
	}

	return FALSE;
}

BOOL CHttpRequest::SetPathTranslated()  {
	static const DWORD dwExtraAlloc = 200;
	CHAR szBuf[MAX_PATH + 1];
	CHAR *szPathInfo;
	DWORD dwBufLen;
	DWORD ccPathInfo;

	DEBUGCHK(!m_pszPathTranslated);

	if (m_pszPathInfo) {
		ccPathInfo = strlen(m_pszPathInfo);

		if (ccPathInfo+1 < sizeof(szBuf)) {
			dwBufLen = sizeof(szBuf);
			strcpy(szBuf,m_pszPathInfo);
			szPathInfo = szBuf;
		}
		else {
			// we alloc a little more than we need in case ServerSupportFunction(HSE_REQ_MAP_URL_TO_PATH) wants a bigger buffer.
			if (NULL == (szPathInfo = MySzAllocA(ccPathInfo+dwExtraAlloc)))
				return FALSE;

			memcpy(szPathInfo,m_pszPathInfo,ccPathInfo+1);
			dwBufLen = ccPathInfo + dwExtraAlloc;
		}
	}
	else {
		// On IIS, if no PATH_INFO variable is used,
		// PATH_TRANSLATED is set to the mapping of the "/" directory, no matter
		// what directory the isapi was called from.
		strcpy(szBuf,"/");
		szPathInfo = szBuf;
		ccPathInfo = 1;
		dwBufLen = sizeof(szBuf);
	}

	if (!ServerSupportFunction(HSE_REQ_MAP_URL_TO_PATH,szPathInfo,&dwBufLen,0)) {
		if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
			if (szPathInfo != szBuf)
				g_funcFree(szPathInfo,g_pvFreeData);

			if (NULL == (szPathInfo = MySzAllocA(dwBufLen)))
				return FALSE;

			if (m_pszPathInfo)
				memcpy(szPathInfo,m_pszPathInfo,ccPathInfo+1);
			else
				strcpy(szPathInfo,"/");

			// there's a number of quasi-legitimate reasons a second call could fail (for instance
			// an ISAPI filter not working correctly), so we just give up and won't set PathTranslated info but don't fail request.
			if (! ServerSupportFunction(HSE_REQ_MAP_URL_TO_PATH,szPathInfo,&dwBufLen,0))
				g_funcFree(szPathInfo,g_pvFreeData);
			else
				m_pszPathTranslated = szPathInfo;
		}
		// else... ServerSupportFunction failed on something other than buf not large enough, fair enough.  Don't end session based on this.
	}
	else {
		if (szPathInfo == szBuf) {
			// make a copy of stack allocated buffer.
			if (NULL == (m_pszPathTranslated = MySzDupA(szBuf)))
				return FALSE;
		}
		else
			m_pszPathTranslated = szPathInfo; // we've alloc'd already.
	}
	return TRUE;
}

const CHAR g_szHexDigits[] = "0123456789abcdef";


BOOL CHttpRequest::WriteClient(PVOID pvBuf, PDWORD pdwSize, BOOL fFromFilter) {
	// On a HEAD request to an ASP page or ISAPI extension results in no data
	// being sent back, however for filters we do send data back when they 
	// tell us to with WriteClient call.
	if (m_idMethod == VERB_HEAD && !fFromFilter)
		return TRUE;

	// are we buffering?
	if (m_fBufferedResponse) {
		return m_bufRespBody.AppendData((PSTR) pvBuf, (int) *pdwSize);
	}

	return SendData((PSTR) pvBuf, *pdwSize,TRUE);
}

//  Acts as the custom header class (for Filters call to AddHeader, SetHeader
//  and for ASP Call to AddHeader and for ASP Cookie handler.

//  We made this function part of the class because there's no reason to memcpy
//  data into a temp buffer before memcpy'ing it into the real buffer.

BOOL CBuffer::AddHeader(PCSTR pszName, PCSTR pszValue, BOOL fAddColon) {
	DEBUG_CODE_INIT;
	BOOL ret = FALSE;
	PSTR pszTrav;

	if (!pszName || !pszValue) {
		DEBUGCHK(0);
		return FALSE;
	}

	int cbName  = strlen(pszName);
	int cbValue = strlen(pszValue);

	//  we need a buffer size of pszName + pszValue, a space, a trailing \r\n, and \0
	int cbTotal;
	SafeInt <DWORD> cbTotalSafe;

	// Use safeInt class to detect integer overflow.
	cbTotalSafe = cbName;
	cbTotalSafe += cbValue;
	cbTotalSafe += (CONSTSIZEOF("\r\n") + 1); // OK to do '+' in RHS expression because RHS is constant int.
	cbTotalSafe += (fAddColon ? 1 : 0);
	cbTotal = cbTotalSafe.Value();

	if ( ! AllocMem( cbTotal ))
		myleave(900);

	pszTrav = m_pszBuf + m_iNextIn;
	memcpy(pszTrav, pszName, cbName);
	pszTrav += cbName;

	// put space between name and value and colon if needed. 
	if (fAddColon)
		*pszTrav++ = ':';

	*pszTrav++ = ' ';  	

	memcpy(pszTrav, pszValue, cbValue);
	memcpy(pszTrav + cbValue,"\r\n", CONSTSIZEOF("\r\n"));

	m_iNextIn += cbTotal;
	ret = TRUE;
done:
	DEBUGMSG_ERR(ZONE_RESPONSE,(L"HTTPD: CBuffer::AddHeader failed, err = %d\r\n",err));

	return ret;
}

⌨️ 快捷键说明

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