📄 soapisap.cpp
字号:
// and the number of threads.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void RemoveRegInfo()
{
HRESULT hr;
HKEY hKey = (HKEY) INVALID_HANDLE_VALUE;
#ifndef UNDER_CE
DWORD dwVal;
#endif
if( (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, g_wszThreadsParentRegKey, 0,
KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
&hKey)) || hKey == INVALID_HANDLE_VALUE )
{
return;
}
if (ERROR_SUCCESS != RegDeleteKey( hKey, L"SOAPISAP"))
{
hr = GetLastError();
}
RegCloseKey(hKey);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: DllRegisterServer
//
// parameters:
//
// description:
// Adds entries to the system registry
// Registers .wsdl extension for POSTs to our ISAPI
// IIS version 5 lists only the allowed verbs, while IIS version 4 lists only
// the disallowed verbs
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
const WCHAR g_ScriptMapWStr[] = L".wsdl,%s,1,GET,POST,HEAD";
const WCHAR g_ScriptMapWStrIIS4[] = L".wsdl,%s,1,PUT,DELETE,TRACE";
STDAPI DllRegisterServer(void)
{
#ifndef UNDER_CE
HRESULT hr = S_OK;
CAutoRefc<IMSAdminBase> pAdminBase;
METADATA_HANDLE hMD = 0;
METADATA_RECORD mdRec;
DWORD wch;
WCHAR wszModuleName[MAX_RES_STRING_SIZE+1];
WCHAR * tempbuf = NULL;
WCHAR * pwstr;
BOOL bIsIIS4;
// Skip the registration if this is a Win9x platform
if (g_fIsWin9x)
return S_OK;
SetRegInfo();
// get a pointer to the IIS Admin Base Object
hr = CoCreateInstance(
CLSID_MSAdminBase,
NULL, CLSCTX_ALL,
IID_IMSAdminBase,
(void **) &pAdminBase);
if (hr != S_OK)
{
// No IIS is installed, return silently
return S_OK;
}
// Obtain the Metadata File extensions list
CHK(GetMetadataExtensions(pAdminBase, &hMD, &mdRec, &tempbuf));
// Remove previously existing .soap extension
wch = mdRec.dwMDDataLen / sizeof(WCHAR);
RemoveSoapExt(tempbuf, &wch);
bIsIIS4 = IsIISVersion4(tempbuf, wch);
// Add current .soap extension
pwstr = (WCHAR *)tempbuf + wch;
// Remove all 0's, except leave one if there are other extensions
while ( (pwstr > tempbuf) && (*(pwstr-1) == (WCHAR)0))
pwstr--;
if ( (pwstr > tempbuf) && (*(pwstr-1) != (WCHAR)0))
*pwstr++ = (WCHAR) 0;
mdRec.dwMDDataLen = (pwstr - tempbuf) * sizeof(WCHAR);
wch = GetModuleFileName(g_hInstance, wszModuleName, MAX_RES_STRING_SIZE);
if (bIsIIS4)
wch = swprintf(pwstr, g_ScriptMapWStrIIS4, wszModuleName);
else
wch = swprintf(pwstr, g_ScriptMapWStr, wszModuleName);
// Need two 0's at the end
pwstr[wch++] = (WCHAR)0;
pwstr[wch++] = (WCHAR)0;
mdRec.dwMDDataLen += wch * sizeof(WCHAR);
CHK(pAdminBase->SetData(
hMD,
L"/",
&mdRec));
Cleanup:
if (hMD)
pAdminBase->CloseKey(hMD);
if (tempbuf)
delete [] tempbuf;
#else
HRESULT hr = S_OK;
#endif
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: DllUnregisterServer()
//
// parameters:
//
// description:
// Removes entries from the system registry
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
STDAPI DllUnregisterServer(void)
{
#ifndef UNDER_CE
HRESULT hr;
CAutoRefc<IMSAdminBase> pAdminBase;
METADATA_HANDLE hMD = 0;
METADATA_RECORD mdRec;
DWORD wch;
CAutoRg<WCHAR> tempbuf(NULL);
WCHAR * pwstr;
// Skip the un-registration if this is a Win9x platform
if (g_fIsWin9x)
return S_OK;
RemoveRegInfo();
// get a pointer to the IIS Admin Base Object
hr = CoCreateInstance(
CLSID_MSAdminBase,
NULL, CLSCTX_ALL,
IID_IMSAdminBase,
(void **) &pAdminBase);
if (hr != S_OK)
{
// No IIS is installed, return silently
return S_OK;
}
// Obtain the Metadata File extensions list
CHK(GetMetadataExtensions(pAdminBase, &hMD, &mdRec, &tempbuf));
// Remove previously existing .soap extension
wch = mdRec.dwMDDataLen / sizeof(WCHAR);
CHK ( RemoveSoapExt(tempbuf, &wch) );
// Save the new data
if (wch <= 1)
{
// If the set is empty, the server will not accept a single NULL
tempbuf[0] = 0;
tempbuf[1] = 0;
wch = 2;
}
mdRec.dwMDDataLen = wch * sizeof(WCHAR);
CHK(pAdminBase->SetData( hMD, L"/", &mdRec));
Cleanup:
if (hMD)
pAdminBase->CloseKey(hMD);
return hr;
#else
return S_OK;
#endif
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: GetMetadataExtensions(IMSAdminBase *pAdminBase, METADATA_HANDLE *phMD, METADATA_RECORD *pmdRec,
// WCHAR ** ppwstrbuf)
//
// parameters:
//
// description:
// Opens the IIS Metadata and obtains a list of registered file extensions
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef UNDER_CE
HRESULT GetMetadataExtensions(IMSAdminBase *pAdminBase,
METADATA_HANDLE *phMD,
METADATA_RECORD *pmdRec,
WCHAR ** ppwstrbuf)
{
HRESULT hr = S_OK;
DWORD wch = 0;
WCHAR * tempbuf = NULL;
CHK(pAdminBase->OpenKey(
METADATA_MASTER_ROOT_HANDLE,
L"/LM/W3SVC",
METADATA_PERMISSION_READ|METADATA_PERMISSION_WRITE,
10000,
phMD));
pmdRec->dwMDIdentifier = MD_SCRIPT_MAPS;
pmdRec->dwMDAttributes = METADATA_INHERIT;
pmdRec->dwMDUserType = IIS_MD_UT_FILE;
pmdRec->dwMDDataType = MULTISZ_METADATA;
pmdRec->dwMDDataLen = 0;
pmdRec->pbMDData = (BYTE *)tempbuf;
pmdRec->dwMDDataTag = 0;
hr = pAdminBase->GetData(
*phMD,
L"/",
pmdRec,
&wch);
if (HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER)
{
// Allocate extra space for new .soap string addition
tempbuf = (WCHAR *) new WCHAR[wch/sizeof(WCHAR) + MAX_RES_STRING_SIZE + 256];
CHK_BOOL (tempbuf, E_OUTOFMEMORY);
pmdRec->pbMDData = (BYTE *)tempbuf;
pmdRec->dwMDDataLen = wch;
pmdRec->dwMDDataTag = 0;
CHK(pAdminBase->GetData(*phMD, L"/", pmdRec, &wch));
}
Cleanup:
*ppwstrbuf = tempbuf;
return hr;
}
#endif
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: RemoveSoapExt(WCHAR * pwchbuf, DWORD *pwch)
//
// parameters:
//
// description:
// Removes the entry .soap extension from the given string buffer and returns the new length
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT RemoveSoapExt(WCHAR * pwchbuf, DWORD *pwch)
{
WCHAR *pwstr;
WCHAR *pwstr2;
#ifndef UNDER_CE
DWORD idx;
#endif
pwstr = pwchbuf;
while (pwstr < (pwchbuf + *pwch - 6))
{
if (wcsncmp(pwstr, L".wsdl,", 6) == 0)
{
// Found the extension
pwstr2 = pwstr;
while ( (pwstr < (pwchbuf + *pwch)) && *pwstr && (*pwstr != (WCHAR)0))
pwstr++;
if (*pwstr == (WCHAR)0)
pwstr++;
// Copy over the rest of the string
while (pwstr < (pwchbuf + *pwch))
{
*pwstr2++ = *pwstr++;
}
*pwch = pwstr2 - pwchbuf;
return S_OK;
}
while (pwstr < (pwchbuf + *pwch) && (*pwstr != (WCHAR)0))
pwstr++;
if (pwstr < (pwchbuf + *pwch))
pwstr++; // Skip the NULL character
}
// No .soap extension
return S_FALSE;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: IsIISVersion4(WCHAR * pwchbuf, DWORD wch)
//
// parameters:
//
// description:
// Checks to see if we are running on IIS version 4 or 5
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef UNDER_CE
BOOL IsIISVersion4(WCHAR * pwchbuf, DWORD wch)
{
WCHAR *pwstr;
WCHAR *pwstr2;
// IIS version 5 lists only the allowed verbs, while IIS version 4 lists only
// the disallowed verbs
// Find any of the .asp, .idc, .idq, .shtm extensions. If they list
// 'GET' then we are running on version 5 or later.
pwstr = pwchbuf;
while (pwstr < (pwchbuf + wch - 6))
{
if ((_wcsnicmp(pwstr, L".htw,", 5) == 0) ||
(_wcsnicmp(pwstr, L".asp,", 5) == 0) ||
(_wcsnicmp(pwstr, L".idc,", 5) == 0) ||
(_wcsnicmp(pwstr, L".idq,", 5) == 0) ||
(_wcsnicmp(pwstr, L".shtm,", 6) == 0) ||
(_wcsnicmp(pwstr, L".asa,", 5) == 0))
{
// Skip the extension part
while ( (pwstr < (pwchbuf + wch)) && *pwstr && (*pwstr != (WCHAR)','))
pwstr++;
if (*pwstr == (WCHAR)',')
{
pwstr++;
// Skip the file path
while ( (pwstr < (pwchbuf + wch)) && *pwstr && (*pwstr != (WCHAR)','))
pwstr++;
if (*pwstr == (WCHAR)',')
{
pwstr++;
// Skip the number
while ( (pwstr < (pwchbuf + wch)) && *pwstr && (*pwstr != (WCHAR)','))
pwstr++;
if (*pwstr == (WCHAR)',')
{
pwstr++;
// We now have the list of verbs
pwstr2 = wcsstr(pwstr, L"GET");
if (!pwstr2)
pwstr2 = wcsstr(pwstr, L"get");
if (pwstr2 && ((pwstr2[3] == (WCHAR)',') || (pwstr2[3] == (WCHAR)0)))
{
// ALLOWED verbs are listed, so it must be IIS version 5
return FALSE;
}
}
}
}
}
while (pwstr < (pwchbuf + wch) && (*pwstr != (WCHAR)0))
pwstr++;
if (pwstr < (pwchbuf + wch))
pwstr++; // Skip the NULL character
}
return TRUE;
}
#endif
#ifdef UNDER_CE
DWORD TerminateISAPIThread(LPVOID param)
{
if (FAILED(CoInitializeEx(NULL,COINIT_MULTITHREADED)))
{
DEBUGMSG(SOAP_ISAPI_DBG,(L"[SOAPISAPI] DLL_PROCESS_ATTACH -- cant CoInitialize\n"));
return FALSE;
}
DEBUGMSG(SOAP_ISAPI_DBG,(L"[SOAPISAPI] starting to sleep on terminate event... ZZZzzzz\n"));
#ifdef DEBUG
DWORD dwRet =
#endif
WaitForSingleObject(g_hTerminateEvent, INFINITE);
ASSERT(dwRet == WAIT_OBJECT_0);
DEBUGMSG(SOAP_ISAPI_DBG,(L"[SOAPISAPI] terminate thread AWAKE\n"));
EnterCriticalSection(&g_cs);
if (--g_cExtensions == 0)
{
TerminateThreadPool();
}
LeaveCriticalSection(&g_cs);
CoUninitialize();
DEBUGMSG(SOAP_ISAPI_DBG,(L"[SOAPISAPI] terminate thread waking up terminate extension\n"));
SetEvent(g_hTerminateEvent);
return 0;
}
#ifdef DEBUG
//note: these are all represented as bits, the first in the list is the least sig
// of the 16
DBGPARAM dpCurSettings = {
TEXT("SoapISAPI"), {
/*D*/
TEXT("General Debug"),
TEXT("Process Attach"),
TEXT(""),
TEXT(""),
/*C*/
TEXT(""),
TEXT(""),
TEXT(""),
TEXT(""),
/*B*/
TEXT(""),
TEXT(""),
TEXT(""),
TEXT(""),
/*A*/
TEXT(""),
TEXT(""),
TEXT(""),
TEXT("")
},0xFFFF
//0x060A
//0x0448
//0x0608
//0x0408
//0x0880
//0x0E34
/*0xABCD*/
};
//0x4080 does 7 and 14 (header collection and first empty...remember to start cnting at 0)
#endif
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -