深度剖析WinPcap之(八)——打开与关闭适配器(8)

本文转自http://eslxf.blog.51cto.com/918801/206420

 

1.5.2.1.1      PacketOpenAdapterNPF函数
函数PacketOpenAdapterNPF()的作用是打开一个使用NPF设备驱动的适配器。该函数被PacketOpenAdapter()AddAdapter()作为内部函数调用。 函数原型如下:
LPADAPTER PacketOpenAdapterNPF(PCHAR AdapterNameA)
参数AdapterNameA字符串包含待打开设备的名称。
函数如果成功,返回一个已经正确初始化的ADAPTER对象的指针。否则返回NULL
函数的主要代码如下:
LPADAPTER PacketOpenAdapterNPF(PCHAR AdapterNameA)
{
    LPADAPTER lpAdapter;
    …
    CHAR SymbolicLinkA[MAX_PATH];
//NPF_DRIVER_NAME定义为"NPF"
    CHAR    NpfDriverName[MAX_WINPCAP_KEY_CHARS] = NPF_DRIVER_NAME;
    CHAR    NpfServiceLocation[MAX_WINPCAP_KEY_CHARS];
 
    /*连接到服务控制管理器*/
    scmHandle = OpenSCManager(NULL, NULL, GENERIC_READ);
       
    if(scmHandle == NULL)
    {//连接到服务控制管理器失败
        error = GetLastError();
    }
    else
    {
/*
*检查NPF服务是否已经存在,
*如果存在则接下来可以分配并初始化ADAPTER对象
*/
 
//设置NPF服务的注册表位置
        StringCchPrintfA(NpfServiceLocation, sizeof(NpfServiceLocation),
"SYSTEM//CurrentControlSet//Services//%s", NpfDriverName);
 
        //检查NPF注册表的键值是已否存在,如果已经存在,
//这意味着驱动已经安装,
//我们不再需要调用PacketInstallDriver()函数安装驱动程序
        KeyRes=RegOpenKeyExA(HKEY_LOCAL_MACHINE,
            NpfServiceLocation,
            0,
            KEY_READ,
            &PathKey);
       
        if(KeyRes != ERROR_SUCCESS)
        {//NPF注册表的键值不存在,调用PacketInstallDriver()函数
            Result = PacketInstallDriver();
        }
        else
        {//NPF注册表的键值已经存在,驱动已经安装
            Result = TRUE;
            RegCloseKey(PathKey);
        }
       
        if (Result)
        { //驱动已经存在,检查NPF服务是否正在运行
           
//打开NPF服务
            svcHandle = OpenServiceA(scmHandle, NpfDriverName,
SERVICE_START | SERVICE_QUERY_STATUS );
            if (svcHandle != NULL)
            {  //获得服务状态
                QuerySStat = QueryServiceStatus(svcHandle, &SStat);
                if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING)
                {//获得服务状态失败或驱动NPF没有运行,启动NPF服务
                    if (StartService(svcHandle, 0, NULL)==0)
                    { //如果不是服务正在运行或服务已经存在的状态,
//就处理错误,函数返回NULL
                        error = GetLastError();
                        if(
error!=ERROR_SERVICE_ALREADY_RUNNING &&
error!=ERROR_ALREADY_EXISTS)
                        {//处理错误,函数返回NULL
                            return NULL;
                        }
                    }              
                }
//驱动NPF已正常运行,关闭服务控制管理器的句柄
                CloseServiceHandle( svcHandle );
                svcHandle = NULL;
            }
            else
            {//打开NPF服务失败
                error = GetLastError();
                SetLastError(error);
            }
        }
        else
        {
            if(KeyRes != ERROR_SUCCESS)
            { //第一次安装驱动程序失败,并且NPF注册表的键值不存在
//再次安装驱动
                Result = PacketInstallDriver();
}
            else
                Result = TRUE;
           
            if (Result) {//NPF的驱动程序已存在
//打开NPF服务          
                svcHandle = OpenServiceA(scmHandle,
                                     NpfDriverName,SERVICE_START);
                if (svcHandle != NULL)
                {//打开NPF服务成功,获取NPF服务的状态
                    QuerySStat = QueryServiceStatus(svcHandle, &SStat);
                    if(!QuerySStat ||
SStat.dwCurrentState != SERVICE_RUNNING)
{//获得服务状态失败或驱动NPF没有运行,启动NPF服务
                        if (StartService(svcHandle, 0, NULL)==0){
                            //如果不是服务正在运行或服务已经存在的状态,
//就处理错误,函数返回NULL
                            if(error!=ERROR_SERVICE_ALREADY_RUNNING &&
                                error!=ERROR_ALREADY_EXISTS)
                            {
                                return NULL;
                            }
                        }
                    }
    //驱动NPF已正常运行,关闭服务控制管理器的句柄
                    CloseServiceHandle( svcHandle );
                    svcHandle = NULL;
                }
                else{
//打开NPF服务失败,设置错误状态
                    error = GetLastError();
                    SetLastError(error);
                }
            }
        }
    }
 
if (scmHandle != NULL) //关闭服务控制管理器的句柄
CloseServiceHandle(scmHandle);
 
    /*分配ADAPTER结构体的的内存空间 */
    lpAdapter=(LPADAPTER)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,
 sizeof(ADAPTER));
    if (lpAdapter==NULL)
    {//分配失败,函数返回NULL;
        …
        return NULL;
    }
    //设置单个数据包发送的次数为一次
    lpAdapter->NumWrites=1;
 
//从原始的设备名创建NPF设备的名称
#define DEVICE_PREFIX "//Device//"
    if (LOWORD(GetVersion()) == 4)
    {
        //操作系统为Windows NT 4.0Windows 95Windows 98、或 Windows Me的处理
              …
    }
    else
    {
        if (strlen(AdapterNameA) > strlen(DEVICE_PREFIX))
        {
            StringCchPrintfA(SymbolicLinkA, MAX_PATH,
".//Global//%s", AdapterNameA + strlen(DEVICE_PREFIX));
        }
        else
        {
            ZeroMemory(SymbolicLinkA, sizeof(SymbolicLinkA));
        }
    }
   ---------------待续---------------------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值