安装LSP

/*

安装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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值