📄 extns.cpp
字号:
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 + -