int iError;
g_NextProcTable.lpWSPShutdown(s, SD_BOTH, &iError);
*lpErrno = WSAECONNABORTED;
ODS(L" deny a sendto ");
return SOCKET_ERROR;
}
return g_NextProcTable.lpWSPSendTo(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpTo
, iTolen, lpOverlapped, lpCompletionRoutine, lpThreadId, lpErrno);
}
int WSPAPI WSPStartup(
WORD wVersionRequested,
LPWSPDATA lpWSPData,
LPWSAPROTOCOL_INFO lpProtocolInfo,
WSPUPCALLTABLE UpcallTable,
LPWSPPROC_TABLE lpProcTable
)
{
ODS1(L" WSPStartup... %s \n", g_szCurrentApp);
if(lpProtocolInfo->ProtocolChain.ChainLen <= 1)
{
return WSAEPROVIDERFAILEDINIT;
}
// 保存向上调用的函数表指针(这里我们不使用它)
g_pUpCallTable = UpcallTable;
// 枚举协议,找到下层协议的WSAPROTOCOL_INFOW结构
WSAPROTOCOL_INFOW NextProtocolInfo;
int nTotalProtos;
LPWSAPROTOCOL_INFOW pProtoInfo = GetProvider(&nTotalProtos);
// 下层入口ID
DWORD dwBaseEntryId = lpProtocolInfo->ProtocolChain.ChainEntries ;
for(int i=0; i<nTotalProtos; i++)
{
if(pProtoInfo[i].dwCatalogEntryId == dwBaseEntryId)
{
memcpy(&NextProtocolInfo, &pProtoInfo[i], sizeof(NextProtocolInfo));
break;
}
}
if(i >= nTotalProtos)
{
ODS(L" WSPStartup: Can not find underlying protocol \n");
return WSAEPROVIDERFAILEDINIT;
}
// 加载下层协议的DLL
int nError;
TCHAR szBaseProviderDll[MAX_PATH];
int nLen = MAX_PATH;
// 取得下层提供程序DLL路径
if(::WSCGetProviderPath(&NextProtocolInfo.ProviderId, szBaseProviderDll, &nLen, &nError) == SOCKET_ERROR)
{
ODS1(L" WSPStartup: WSCGetProviderPath() failed %d \n", nError);
return WSAEPROVIDERFAILEDINIT;
}
if(!::ExpandEnvironmentStrings(szBaseProviderDll, szBaseProviderDll, MAX_PATH))
{
ODS1(L" WSPStartup: ExpandEnvironmentStrings() failed %d \n", ::GetLastError());
return WSAEPROVIDERFAILEDINIT;
}
// 加载下层提供程序
HMODULE hModule = ::LoadLibrary(szBaseProviderDll);
if(hModule == NULL)
{
ODS1(L" WSPStartup: LoadLibrary() failed %d \n", ::GetLastError());
return WSAEPROVIDERFAILEDINIT;
}
// 导入下层提供程序的WSPStartup函数
LPWSPSTARTUP pfnWSPStartup = NULL;
pfnWSPStartup = (LPWSPSTARTUP)::GetProcAddress(hModule, "WSPStartup");
if(pfnWSPStartup == NULL)
{
ODS1(L" WSPStartup: GetProcAddress() failed %d \n", ::GetLastError());
return WSAEPROVIDERFAILEDINIT;
}
// 调用下层提供程序的WSPStartup函数
LPWSAPROTOCOL_INFOW pInfo = lpProtocolInfo;
if(NextProtocolInfo.ProtocolChain.ChainLen == BASE_PROTOCOL)
pInfo = &NextProtocolInfo;
int nRet = pfnWSPStartup(wVersionRequested, lpWSPData, pInfo, UpcallTable, lpProcTable);
if(nRet != ERROR_SUCCESS)
{
ODS1(L" WSPStartup: underlying provider's WSPStartup() failed %d \n", nRet);
return nRet;
}
// 保存下层提供者的函数表
g_NextProcTable = *lpProcTable;
// 修改传递给上层的函数表,Hook感兴趣的函数,这里做为示例,仅Hook了WSPSendTo函数
// 您还可以Hook其它函数,如WSPSocket、WSPCloseSocket、WSPConnect等
lpProcTable->lpWSPSendTo = WSPSendTo;
FreeProvider(pProtoInfo);
return nRet;
}