/*
安装LSP时,应先安装分层协议,然后安装协议链,最后排序.
*/
#include
#include
#include
#include
#pragma comment(lib,"ws2_32")
#pragma comment(lib,"rpcrt4")
GUID ProviderGuid={0xfa5774ac, 0x5338, 0x4a58,{ 0x89, 0xdf, 0x7b, 0x6b, 0x7f, 0xd0, 0x4a, 0xb5}};
//得到LPWSAPROTOCOL_INFOW数组.
LPWSAPROTOCOL_INFOW GetProvider(LPINT pTotalProtocols)
{
LPWSAPROTOCOL_INFOW lpProtoInfo=NULL;
DWORD dwBufferLen=0;
int nError;
if(SOCKET_ERROR==::WSCEnumProtocols(NULL,lpProtoInfo,&dwBufferLen,&nError))
{
if(WSAENOBUFS==nError)
{
lpProtoInfo=(LPWSAPROTOCOL_INFOW)::GlobalAlloc(GPTR,dwBufferLen);
*pTotalProtocols=::WSCEnumProtocols(NULL,lpProtoInfo,&dwBufferLen,&nError);
}
}
return lpProtoInfo;
}
int InstallProvider(WCHAR *wszDllPath)
{
WCHAR wszLSPName[]=L"MyLSP";
int nError=NO_ERROR;
LPWSAPROTOCOL_INFOW pProtoInfo;
int nProtocols;
WSAPROTOCOL_INFOW UDPLayeredInfo,UDPChainInfo;
DWORD dwUdpOrigCatalogId,dwLayeredCatalogId;
//枚举LPWSAPROTOCOL_INFOW得到UDP的LPWSAPROTOCOL_INFOW,并保存UDP的目录ID.
pProtoInfo=GetProvider(&nProtocols);
for(int i=0;i
{
if(pProtoInfo[i].iAddressFamily==AF_INET&&pProtoInfo[i].iProtocol==IPPROTO_UDP)
{
memcpy(&UDPChainInfo,&pProtoInfo[i],sizeof(UDPChainInfo));
UDPChainInfo.dwServiceFlags1=UDPChainInfo.dwServiceFlags1&~XP1_IFS_HANDLES;
dwUdpOrigCatalogId=pProtoInfo[i].dwCatalogEntryId;
break;
}
}
//安装分层协议
memcpy(&UDPLayeredInfo,&UDPChainInfo,sizeof(UDPLayeredInfo));
wcscpy(UDPLayeredInfo.szProtocol,wszLSPName);
UDPLayeredInfo.ProtocolChain.ChainLen=LAYERED_PROTOCOL;
UDPLayeredInfo.dwProviderFlags|=PFL_HIDDEN;
if(::WSCInstallProvider(&ProviderGuid,wszDllPath,&UDPLayeredInfo,1,&nError)==SOCKET_ERROR)
{
return nError;
}
::GlobalFree(pProtoInfo);
//枚举LPWSAPROTOCOL_INFOW,保存刚刚安装的UDP分层协议的目录ID
pProtoInfo=GetProvider(&nProtocols);
for(int i=0;i
{
if(::memcmp(&pProtoInfo[i].ProviderId,&ProviderGuid,sizeof(ProviderGuid))==0)
{
dwLayeredCatalogId=pProtoInfo[i].dwCatalogEntryId;
break;
}
}
//配置协议链的一些属性
WCHAR wszChainName[WSAPROTOCOL_LEN+1];
swprintf(wszChainName,L"%ws over %ws",wszLSPName,UDPChainInfo.szProtocol);
wcscpy(UDPChainInfo.szProtocol,wszChainName);
//整理原来的协议链,让原来的第2个移到第3的位置,以此内推.将第1个的位置给刚刚安装的分层协议.
if(UDPChainInfo.ProtocolChain.ChainLen==1)
UDPChainInfo.ProtocolChain.ChainEntries[1]=dwUdpOrigCatalogId;
else
{
for(int i=UDPChainInfo.ProtocolChain.ChainLen;i>1;i--)
{
UDPChainInfo.ProtocolChain.ChainEntries[i]=UDPChainInfo.ProtocolChain.ChainEntries[i-1];
}
}
UDPChainInfo.ProtocolChain.ChainLen++;
//UDPChainInfo.ProtocolChain.ChainEntries[0]即第1的位置.
UDPChainInfo.ProtocolChain.ChainEntries[0]=dwLayeredCatalogId;
//创建GUID并安装协议链.
GUID ProviderChainGuid;
if(::UuidCreate(&ProviderChainGuid)==RPC_S_OK)
{
if(::WSCInstallProvider(&ProviderChainGuid,wszDllPath,&UDPChainInfo,1,&nError)==SOCKET_ERROR)
{
return nError;
}
}
else
return ::GetLastError();
::GlobalFree(pProtoInfo);
/*得到LPWSAPROTOCOL_INFOW数组,并通过两次枚举,将刚刚安装的LSP置于LPWSAPROTOCOL_INFOW顺序的前端*/
pProtoInfo=GetProvider(&nProtocols);
DWORD dwIds[20];
int nIndex=0;
for(int i=0;i
{
if(pProtoInfo[i].ProtocolChain.ChainLen>1&&pProtoInfo[0].dwCatalogEntryId==dwLayeredCatalogId)
{
dwIds[nIndex++]=pProtoInfo[i].dwCatalogEntryId;
}
}
for(int i=0;i
{
if(pProtoInfo[i].ProtocolChain.ChainLen<=1&&pProtoInfo[0].dwCatalogEntryId!=dwLayeredCatalogId)
{
dwIds[nIndex++]=pProtoInfo[i].dwCatalogEntryId;
}
}
//重新排序
nError=::WSCWriteProviderOrder(dwIds,nIndex);
::GlobalFree(pProtoInfo);
return nError;
}